SlideShare a Scribd company logo
1 of 31
Essentials of MultithreadedSystem Programming in C++ Shuo Chen 2011/02 blog.csdn.net/Solstice giantchen@gmail.com @bnu_chenshuo
Contents Challenges in multithreaded system programming Thread safety of C and C++ libraries RAII and fork() fork() and signal handling in multithreaded programs 2011/02 Shuo Chen (blog.csdn.net/Solstice) 2
Audience: C++ programmers Familiar with Pthreads and Sockets API Knows thread safety, deadlock, race condition, etc. In a word: read through APUE2e and UNP3e (vol. 1) by W. Richard Stevens et al. All discussions are based on Linux 2.6.x, x >= 28 There are new syscalls, egsignalfd, eventfd, and timerfd x86 and x64 platforms 2011/02 Shuo Chen (blog.csdn.net/Solstice) 3
Multi-threaded system programming Multithreading is inevitable in this multi-core era The difficulties are not learning synchronization primitives (mutexes, condition variables) ~10 functions are sufficient to do it right But understanding interactions between existing system calls and library functions Understands how threads affect system design Use it wisely and effectively Avoid common pitfalls and fallacies 2011/02 Shuo Chen (blog.csdn.net/Solstice) 4
11 essential Pthreads functions 11 out of 110+ pthreads functions 2 -> create and join threads 4 -> init/destroy, lock/unlock mutexes 5 -> init/destroy, wait/signal/broadcast condvars Think twice if you need more Some are okay, eg. once and key, maybe rwlock Some are bad, eg. cancel and kill, semaphores Check muduo/base for encapsulation in C++ http://code.google.com/p/muduo http://github.com/chenshuo/recipes   click  thread 2011/02 Shuo Chen (blog.csdn.net/Solstice) 5
An asynchronous world Never assume the sequence of events without proper synchronization. Knows happens-before relation, memory visibility, etc. The effect of an interaction between two [thread]s must be independent of the speed at which it is carried out. --- Brinch Hansen 1973 2011/02 Shuo Chen (blog.csdn.net/Solstice) 6
Standards and practices Although the latest official standards of C and C++ languages (C99 and C++03) do not say a word about process or thread We write multi-process and/or multi-threaded C/C++ programs in real life, as a real-world need We can’t wait it to be standardized, as standards usually fall behind practices for years btw, if there are not real life multi-threads programs , how do people what/how to standardize? We adhere to some de facto standards A lot simpler if we focus on one hardware and one OS 2011/02 Shuo Chen (blog.csdn.net/Solstice) 7
Thread identifier on Linux Use pid_t as thread id, instead of pthread_t, on Linux pthread_tthid = pthread_self(), thid is opaque (uintptr_t) pid_ttid = ::gettid(), tid is task id, usually a small integer /proc/tid/, /proc/pid/task/tid/, ps, top all work fine How to implement gettid() efficiently? Thread local? gettid(2) is a syscall, but the output should never change getpid(2) caches the result, should gettid() do the same? What if fork(), will it caches the old value in child proc? How about pthread_atfork() to clear it up? Check muduo/base/Thread.cc for details 2011/02 Shuo Chen (blog.csdn.net/Solstice) 8
Creation of threads A library should not create its own ‘background’ thread  without prior informed consent Makes a program non-forkable Never create thread before main() Avoid creating thread in ctor of static or global object Breaks static objects constructing, eg. protobuf registering The number of threads created should be independentof system load, eg. # of connections, # of requests otherwise non-scalable Reuse threads, by assign multiple roles to it Doing IO and timer with muduoEventLoop class For simple task, do it within IO callbacks in IO threads 2011/02 Shuo Chen (blog.csdn.net/Solstice) 9
Three ways of termination http://blog.csdn.net/program_think/archive/2009/03/14/3991107.aspx Natural death – return from thread function, good Suicide – call pthread_exit() Mudered – killed by pthread_cancel() Rule: let it die, never suicide or murder a thread Why? inherently deadlock-prone: no chance to unlock Design your program so that a thread can be waken up and safely exits For reference Java Thread.{stop, suspend and destroy} are deprecated Boost Threads doesn’t provide thread::cancel() 2011/02 Shuo Chen (blog.csdn.net/Solstice) 10
pthread_cancel() and C++ In C, we have concept of ‘cancellation point’ In C++, pthread_cancel() throws an exception in that thread, helps unwinding objects on stack The exception must reach the outmost function, otherwise core dump: FATAL: exception not rethrown Aborted (core dumped) Always rethrow in catch(…) cause Ulrich Drepper “Cancellation and C++ Exceptions” Better: never cancel or kill a thread 2011/02 Shuo Chen (blog.csdn.net/Solstice) 11
exit() is not thread safe in C++ exit() destructs static or global objects, (_exit() doesn’t) The destructor may try to hold a lock The caller  function may have held the same lock already End up in a dead lock Check following code for an example of dead lock  github.com/chenshuo/recipes/blob/master/thread/test/ExitDeadLock.cc How to quit a multi-threaded program safely? An irregular but simple solution: make a process killable, eg. p.29  blog.csdn.net/Solstice/archive/2010/10/19/5950190.aspx It’s not fault of exit(), but static or global objects Try to avoid static or global objects in C++, except for PODs 2011/02 Shuo Chen (blog.csdn.net/Solstice) 12
Thread local __thread in g++ Thread safe by natural, unless escaped to other thread More efficient implementation,  than pthread_key_t See “ELF Handling For Thread-Local Storage” In C++, must be initialized with constant-expression No 	__thread string t_obj("Chen Shuo"); No 	__thread string* t_obj = new string; Only 	__thread string* t_obj = NULL; More rules:  http://gcc.gnu.org/onlinedocs/gcc/Thread_002dLocal.html Use pthread_key_t if you want auto destruction 2011/02 Shuo Chen (blog.csdn.net/Solstice) 13
Use non-recursive mutex only A basic assumption of holding a mutex Once I lock it, I can modify the guarded object safely Which is not true for recursive mutex, eg. http://blog.csdn.net/Solstice/archive/2010/02/12/5307710.aspx#_Toc11928 Recursive mutexes by David Butenhof http://zaval.org/resources/library/butenhof1.html  Recursive locks - a blessing or a curse?   http://www.thinkingparallel.com/2006/09/27/recursive-locks-a-blessing-or-a-curse/ 2011/02 Shuo Chen (blog.csdn.net/Solstice) 14
Impacts of introducing threads Threading is a late patch to OS kernel Unix kernel and API formed in early 1970s First implementation of threads emerged in early 1990s Breaks lots of assumptions made during the 20 years Library functions with side effects must be revisited malloc/free, fread/fseekcan be made thread-safe with locks Functions that return or use static allocated space are not thread safe but may have thread-safe variants asctime_r, ctime_r, gmtime_r, rand_r, stderror_r, strtok_r errno is not an ‘extern int’, but a per-thread value extern int *__errno_location(void); #define errno (*__errno_location()) 2011/02 Shuo Chen (blog.csdn.net/Solstice) 15
Thread safety of C library Individual system calls must be thread safe Be caution of interfering of same file descriptor from multiple threads Most of glibc library functions are thread safe nowadays Counterintuitively, Posix standards lists functions thatare not required to be thread safe, it's a black list. http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09 2.9.1 Thread-Safety : All functions defined by this volume of POSIX.1-2008 shall be thread-safe, except that the following functions need not be thread-safe. Notably, getenv/putenv/setenv/system() are not safe 2011/02 Shuo Chen (blog.csdn.net/Solstice) 16
FILE* functions are thread safe Read ‘man flockfile’, but they are not composable, eg. fseek(), followed by fread() The file position may change during the course by a different thread Wrap with flockfile(FILE*) and funlockfile(FILE*)  Same applies to lseek(2) and read(2), but how to lock? Use pread(2) instead, which doesn’t change the file offset In general, a function that calls two thread-safe functions is not guaranteed to be thread-safe Just like exception-safety, thread-safety is not composable 2011/02 Shuo Chen (blog.csdn.net/Solstice) 17
Thread safety is not composable A solution works in single-threaded program may not apply to multi-threaded program. Any solution calls two or more thread safe function are not necessarily correct in multi-threaded program What’s the time in London now? Program runs in New York string oldTz = getenv("TZ");             // save TZ putenv("TZ=Europe/London"); tzset();     // set TZ to London struct tm localTimeInLN = *localtime(time(NULL)); setenv("TZ", oldTz.c_str(), 1); tzset(); // restore old TZ This code impacts localtime() in other threads Thread safe functions are not composable unless you carefully design the interface and interactions 2011/02 Shuo Chen (blog.csdn.net/Solstice) 18
Thread safety of C++ std library Although not required by the standard, the de facto says Unshared objects are independent: Two threads can freely use different objects without any special action on the caller's part. We call it "same level as built-in types." This applies to STL containers like map, vector, string Pure functions are safe, eg. Most of STL algorithms. The global cin/cout objects are shared by threads, and are not thread safe. Moreover, they can't be made safe cout << a << b;  cout.operator<<(a).operator<<(b); Two function calls can be interrupted by another thread Use printf(3) instead, it's thread safe and atomic. Allocators must be thread safe, as they are shared 2011/02 Shuo Chen (blog.csdn.net/Solstice) 19
Thread-Safe vs. Thread-Efficient printf(3) and malloc(3) are thread safe, but not necessarily efficient enough, esp. on multi-cores printf(3) locks FILE* stdout, synchronizes threads not good for multi-threaded logging, we need a better lib your default malloc(3) may not optimized for multi-threads and multi-cores it may lock global heap for each allocation try tcmalloc, Google's thread-cache malloc see Intel. Is your memory management multi-core ready? http://software.intel.com/en-us/blogs/2009/08/21/is-your-memory-management-multi-core-ready/ 2011/02 Shuo Chen (blog.csdn.net/Solstice) 20
Operate one fd in one thread Although system calls of file descriptors are safe What if a thread close a fd when other thread is block reading it? What happens if a thread add a fd to epoll watch list while other thread is epoll_wait()ing it? What happens if two threads poll same fd, and find it readable simultaneously? What if two threads read the same TCP socket but each get partial data? How do you tell which part comes first? Rule: all operations on one file descriptor should happen in one thread, make your life a lot easier 2011/02 Shuo Chen (blog.csdn.net/Solstice) 21
File descriptors in threads File descriptors are small integers, unlike HANDLE When create a new fd, kernel picks the lowest unused one Higher possibility of cross-talk, if careless, eg. A fd shared by two threads The first thread have just close()d it The second is about to read() it But a third thread happened to create a new fd with same id (the lowest available int reused) during the period What does the second thread read from? Any other impact? Solution: manage resource with RAII idiom And use the usual technique to manage object life cycles 2011/02 Shuo Chen (blog.csdn.net/Solstice) 22
C++ and fork() A object could construct once but destruct twice int main() { Foofoo; // call 'Foo::Foo'   fork();  // fork to two process // call 'Foo::~Foo' in parent *and* child processes } It might be a problem, if Foo owns some resource that is not inherited by child process Again, avoid static or global objects in C++ In child process, the object may not be properly  initialized A global muduo::Timestamp startTime(now()) is wrong 2011/02 Shuo Chen (blog.csdn.net/Solstice) 23
RAII and fork() fork() doesn't copy all state Open file descriptors are inherited by child process But the offset of file are independent The child does not inherit its parent's memory locks (mlock(2), mlockall(2)) record locks from its parent (fcntl(2)) timers from its parent (setitimer(2), alarm(2), timer_create(2)), and others So the RAII idiom may not work well in fork()ed process A RAII class that wraps timer_create/timer_delete in ctor/dtor may fail in child process after fork() Use pthread_atfork() as the last resort 2011/02 Shuo Chen (blog.csdn.net/Solstice) 24
C++ and threads Use scoped lock guard only, check muduo/base/Mutex.h Don't allow exceptions to propagate across module boundaries don't let exception propagate out of the thread main function, catch all exceptions in the outer-most function But, rethrow the one of pthread_cancel(), as we said before Don't allow exceptions to propagate out of your callback, esp. callbacks from C library, eg. the init_routine registered to pthread_once() Better: don't use exception in C++ 2011/02 Shuo Chen (blog.csdn.net/Solstice) 25
Threads and fork() The fork() model doesn’t fit well in threads A fundamental flaw of PosixOSes, as other threads disappear in child, the state is not consistent in child proc After fork a multi-threaded program you may only call async-signal-safe functions in child, as if in signal handler malloc() is not safe, other thread may hold the lock when fork()ing, and no chance to unlock in the new process So does printf(), pthread_* and others. The only safe way to use fork() in a multi-threaded program is calling exec() immediately in child process And make sure set close-on-exec flag on every file descriptors in parent process for security reasons. 2011/02 Shuo Chen (blog.csdn.net/Solstice) 26
Signals and threads The whole Posix signal mechanism is a shit Only async-signal-safe functions can be called in signal handler, also called 'reentrant functions' Most of the functions are notasync-signal-safe, except those listed in Posix standards, so it's a white list http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03_03 'man 7 signal' to get the list on Linux  None of pthread_* are not async-signal-safe, you can't notify a condvar or lock a mutex in signal handler Surprisely, gettimeofday(2) is not async-signal-safe 2011/02 Shuo Chen (blog.csdn.net/Solstice) 27
Deal with signals in MT programs Rule 1: do not use signal don't use it as IPC, eg. SIGUSR1, SIGUSR2, SIGINT, SIGHUP don't use library functions built upon signals, eg. alarm, sleep, usleep, timer_create, etc. Rule 2: when you absolutely need, convert an async signal  to synchronous file descriptor readable event use signalfd in high Linux kernel version Normally,  the set of signals to be received via the file descriptor should be blocked using pthread_sigmask(3), to prevent the signals being handled according to their default dispositions. or open a pipe(2), write(2) one byte in signal handler, and read(2) or poll(2) it in main thread 2011/02 Shuo Chen (blog.csdn.net/Solstice) 28
Other resources http://pubs.opengroup.org/onlinepubs/9699919799/ http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them http://www.linuxprogrammingblog.com/all-about-linux-signals http://www.cppblog.com/lymons/archive/2008/06/01/51838.html Seven posts in http://www.cppblog.com/lymons/category/9446.html 2011/02 Shuo Chen (blog.csdn.net/Solstice) 29
To be continued Essential of non-blocking network programming in C++ Birth of a reactor – design and implementation of Muduo 2011/02 Shuo Chen (blog.csdn.net/Solstice) 30
Avoid static or global objects Except for PODs 2011/02 Shuo Chen (blog.csdn.net/Solstice) 31

More Related Content

What's hot

Process' Virtual Address Space in GNU/Linux
Process' Virtual Address Space in GNU/LinuxProcess' Virtual Address Space in GNU/Linux
Process' Virtual Address Space in GNU/LinuxVarun Mahajan
 
Static keyword ppt
Static keyword pptStatic keyword ppt
Static keyword pptVinod Kumar
 
Muduo network library
Muduo network libraryMuduo network library
Muduo network libraryShuo Chen
 
Finalize() method
Finalize() methodFinalize() method
Finalize() methodJadavsejal
 
[若渴計畫] Challenges and Solutions of Window Remote Shellcode
[若渴計畫] Challenges and Solutions of Window Remote Shellcode[若渴計畫] Challenges and Solutions of Window Remote Shellcode
[若渴計畫] Challenges and Solutions of Window Remote ShellcodeAj MaChInE
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in ScalaHermann Hueck
 
[OOP - Lec 19] Static Member Functions
[OOP - Lec 19] Static Member Functions[OOP - Lec 19] Static Member Functions
[OOP - Lec 19] Static Member FunctionsMuhammad Hammad Waseem
 
The Linux Block Layer - Built for Fast Storage
The Linux Block Layer - Built for Fast StorageThe Linux Block Layer - Built for Fast Storage
The Linux Block Layer - Built for Fast StorageKernel TLV
 
Collections Framework
Collections FrameworkCollections Framework
Collections FrameworkSunil OS
 
Process Address Space: The way to create virtual address (page table) of user...
Process Address Space: The way to create virtual address (page table) of user...Process Address Space: The way to create virtual address (page table) of user...
Process Address Space: The way to create virtual address (page table) of user...Adrian Huang
 
Linux Memory Management
Linux Memory ManagementLinux Memory Management
Linux Memory ManagementNi Zo-Ma
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Philip Schwarz
 
Java exception handling
Java exception handlingJava exception handling
Java exception handlingBHUVIJAYAVELU
 
Reactive programming with examples
Reactive programming with examplesReactive programming with examples
Reactive programming with examplesPeter Lawrey
 

What's hot (20)

Process' Virtual Address Space in GNU/Linux
Process' Virtual Address Space in GNU/LinuxProcess' Virtual Address Space in GNU/Linux
Process' Virtual Address Space in GNU/Linux
 
Constructor
ConstructorConstructor
Constructor
 
Static keyword ppt
Static keyword pptStatic keyword ppt
Static keyword ppt
 
Muduo network library
Muduo network libraryMuduo network library
Muduo network library
 
Finalize() method
Finalize() methodFinalize() method
Finalize() method
 
[若渴計畫] Challenges and Solutions of Window Remote Shellcode
[若渴計畫] Challenges and Solutions of Window Remote Shellcode[若渴計畫] Challenges and Solutions of Window Remote Shellcode
[若渴計畫] Challenges and Solutions of Window Remote Shellcode
 
tmux
tmuxtmux
tmux
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in Scala
 
How A Compiler Works: GNU Toolchain
How A Compiler Works: GNU ToolchainHow A Compiler Works: GNU Toolchain
How A Compiler Works: GNU Toolchain
 
[OOP - Lec 19] Static Member Functions
[OOP - Lec 19] Static Member Functions[OOP - Lec 19] Static Member Functions
[OOP - Lec 19] Static Member Functions
 
The Linux Block Layer - Built for Fast Storage
The Linux Block Layer - Built for Fast StorageThe Linux Block Layer - Built for Fast Storage
The Linux Block Layer - Built for Fast Storage
 
Collections Framework
Collections FrameworkCollections Framework
Collections Framework
 
Process Address Space: The way to create virtual address (page table) of user...
Process Address Space: The way to create virtual address (page table) of user...Process Address Space: The way to create virtual address (page table) of user...
Process Address Space: The way to create virtual address (page table) of user...
 
Linux Memory Management
Linux Memory ManagementLinux Memory Management
Linux Memory Management
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
 
Java exception handling
Java exception handlingJava exception handling
Java exception handling
 
Reactive programming with examples
Reactive programming with examplesReactive programming with examples
Reactive programming with examples
 
C++ oop
C++ oopC++ oop
C++ oop
 
Java 8 date & time api
Java 8 date & time apiJava 8 date & time api
Java 8 date & time api
 
File Handling In C++
File Handling In C++File Handling In C++
File Handling In C++
 

Viewers also liked

PThreads Vs Win32 Threads
PThreads  Vs  Win32 ThreadsPThreads  Vs  Win32 Threads
PThreads Vs Win32 ThreadsRobert Sayegh
 
Where destructors meet threads
Where destructors meet threadsWhere destructors meet threads
Where destructors meet threadsShuo Chen
 
Tutorial windows service with java (procrun)
Tutorial windows service with java (procrun)Tutorial windows service with java (procrun)
Tutorial windows service with java (procrun)muhammad arif nasution
 
Fork Yeah! The Rise and Development of illumos
Fork Yeah! The Rise and Development of illumosFork Yeah! The Rise and Development of illumos
Fork Yeah! The Rise and Development of illumosbcantrill
 
Efficient logging in multithreaded C++ server
Efficient logging in multithreaded C++ serverEfficient logging in multithreaded C++ server
Efficient logging in multithreaded C++ serverShuo Chen
 
Multithreading Presentation
Multithreading PresentationMultithreading Presentation
Multithreading PresentationNeeraj Kaushik
 
Database, concetti di base
Database, concetti di baseDatabase, concetti di base
Database, concetti di baseantmng
 
Datetime - Julian Date
Datetime - Julian DateDatetime - Julian Date
Datetime - Julian DateShuo Chen
 
thread-clustering
thread-clusteringthread-clustering
thread-clusteringdavidkftam
 
Galvin-operating System(Ch8)
Galvin-operating System(Ch8)Galvin-operating System(Ch8)
Galvin-operating System(Ch8)dsuyal1
 
Lecture5
Lecture5Lecture5
Lecture5jntu
 
C++ Actor Model - You’ve Got Mail ...
C++ Actor Model - You’ve Got Mail ...C++ Actor Model - You’ve Got Mail ...
C++ Actor Model - You’ve Got Mail ...Gianluca Padovani
 

Viewers also liked (20)

PThreads Vs Win32 Threads
PThreads  Vs  Win32 ThreadsPThreads  Vs  Win32 Threads
PThreads Vs Win32 Threads
 
Where destructors meet threads
Where destructors meet threadsWhere destructors meet threads
Where destructors meet threads
 
Concordion java
Concordion javaConcordion java
Concordion java
 
Tutorial windows service with java (procrun)
Tutorial windows service with java (procrun)Tutorial windows service with java (procrun)
Tutorial windows service with java (procrun)
 
Fork Yeah! The Rise and Development of illumos
Fork Yeah! The Rise and Development of illumosFork Yeah! The Rise and Development of illumos
Fork Yeah! The Rise and Development of illumos
 
Zurg part 1
Zurg part 1Zurg part 1
Zurg part 1
 
Efficient logging in multithreaded C++ server
Efficient logging in multithreaded C++ serverEfficient logging in multithreaded C++ server
Efficient logging in multithreaded C++ server
 
Multithreading Presentation
Multithreading PresentationMultithreading Presentation
Multithreading Presentation
 
Database - progettazione
Database - progettazioneDatabase - progettazione
Database - progettazione
 
Database, concetti di base
Database, concetti di baseDatabase, concetti di base
Database, concetti di base
 
Datetime - Julian Date
Datetime - Julian DateDatetime - Julian Date
Datetime - Julian Date
 
Database introduzione
Database introduzioneDatabase introduzione
Database introduzione
 
Deadlock
DeadlockDeadlock
Deadlock
 
Java Threading
Java ThreadingJava Threading
Java Threading
 
thread-clustering
thread-clusteringthread-clustering
thread-clustering
 
Galvin-operating System(Ch8)
Galvin-operating System(Ch8)Galvin-operating System(Ch8)
Galvin-operating System(Ch8)
 
Ch05
Ch05Ch05
Ch05
 
Threading
ThreadingThreading
Threading
 
Lecture5
Lecture5Lecture5
Lecture5
 
C++ Actor Model - You’ve Got Mail ...
C++ Actor Model - You’ve Got Mail ...C++ Actor Model - You’ve Got Mail ...
C++ Actor Model - You’ve Got Mail ...
 

Similar to Essentials of Multithreaded System Programming in C++

Coding for multiple cores
Coding for multiple coresCoding for multiple cores
Coding for multiple coresLee Hanxue
 
Medical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUsMedical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUsDaniel Blezek
 
Threaded Programming
Threaded ProgrammingThreaded Programming
Threaded ProgrammingSri Prasanna
 
Deuce STM - CMP'09
Deuce STM - CMP'09Deuce STM - CMP'09
Deuce STM - CMP'09Guy Korland
 
Rust and Eclipse
Rust and EclipseRust and Eclipse
Rust and EclipseMax Bureck
 
Rust "Hot or Not" at Sioux
Rust "Hot or Not" at SiouxRust "Hot or Not" at Sioux
Rust "Hot or Not" at Siouxnikomatsakis
 
Here comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdfHere comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdfKrystian Zybała
 
Python multithreading
Python multithreadingPython multithreading
Python multithreadingJanu Jahnavi
 
Python multithreading
Python multithreadingPython multithreading
Python multithreadingJanu Jahnavi
 
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)Ovidiu Farauanu
 
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016Christian Schneider
 
Threads and multi threading
Threads and multi threadingThreads and multi threading
Threads and multi threadingAntonio Cesarano
 
Daniel Krasner - High Performance Text Processing with Rosetta
Daniel Krasner - High Performance Text Processing with Rosetta Daniel Krasner - High Performance Text Processing with Rosetta
Daniel Krasner - High Performance Text Processing with Rosetta PyData
 
Track c-High speed transaction-based hw-sw coverification -eve
Track c-High speed transaction-based hw-sw coverification -eveTrack c-High speed transaction-based hw-sw coverification -eve
Track c-High speed transaction-based hw-sw coverification -evechiportal
 
Cross Platform App Development with C++
Cross Platform App Development with C++Cross Platform App Development with C++
Cross Platform App Development with C++Joan Puig Sanz
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and BeyondComicSansMS
 
Rust: Reach Further
Rust: Reach FurtherRust: Reach Further
Rust: Reach Furthernikomatsakis
 

Similar to Essentials of Multithreaded System Programming in C++ (20)

Coding for multiple cores
Coding for multiple coresCoding for multiple cores
Coding for multiple cores
 
Medical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUsMedical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUs
 
Threaded Programming
Threaded ProgrammingThreaded Programming
Threaded Programming
 
Deuce STM - CMP'09
Deuce STM - CMP'09Deuce STM - CMP'09
Deuce STM - CMP'09
 
java_threads.ppt
java_threads.pptjava_threads.ppt
java_threads.ppt
 
Rust and Eclipse
Rust and EclipseRust and Eclipse
Rust and Eclipse
 
Rust "Hot or Not" at Sioux
Rust "Hot or Not" at SiouxRust "Hot or Not" at Sioux
Rust "Hot or Not" at Sioux
 
Here comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdfHere comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdf
 
Python multithreading
Python multithreadingPython multithreading
Python multithreading
 
Python multithreading
Python multithreadingPython multithreading
Python multithreading
 
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
 
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
 
Threads and multi threading
Threads and multi threadingThreads and multi threading
Threads and multi threading
 
Daniel Krasner - High Performance Text Processing with Rosetta
Daniel Krasner - High Performance Text Processing with Rosetta Daniel Krasner - High Performance Text Processing with Rosetta
Daniel Krasner - High Performance Text Processing with Rosetta
 
Track c-High speed transaction-based hw-sw coverification -eve
Track c-High speed transaction-based hw-sw coverification -eveTrack c-High speed transaction-based hw-sw coverification -eve
Track c-High speed transaction-based hw-sw coverification -eve
 
Cross Platform App Development with C++
Cross Platform App Development with C++Cross Platform App Development with C++
Cross Platform App Development with C++
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and Beyond
 
P threads
P threadsP threads
P threads
 
Java Concurrency
Java ConcurrencyJava Concurrency
Java Concurrency
 
Rust: Reach Further
Rust: Reach FurtherRust: Reach Further
Rust: Reach Further
 

Recently uploaded

Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 

Recently uploaded (20)

Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 

Essentials of Multithreaded System Programming in C++

  • 1. Essentials of MultithreadedSystem Programming in C++ Shuo Chen 2011/02 blog.csdn.net/Solstice giantchen@gmail.com @bnu_chenshuo
  • 2. Contents Challenges in multithreaded system programming Thread safety of C and C++ libraries RAII and fork() fork() and signal handling in multithreaded programs 2011/02 Shuo Chen (blog.csdn.net/Solstice) 2
  • 3. Audience: C++ programmers Familiar with Pthreads and Sockets API Knows thread safety, deadlock, race condition, etc. In a word: read through APUE2e and UNP3e (vol. 1) by W. Richard Stevens et al. All discussions are based on Linux 2.6.x, x >= 28 There are new syscalls, egsignalfd, eventfd, and timerfd x86 and x64 platforms 2011/02 Shuo Chen (blog.csdn.net/Solstice) 3
  • 4. Multi-threaded system programming Multithreading is inevitable in this multi-core era The difficulties are not learning synchronization primitives (mutexes, condition variables) ~10 functions are sufficient to do it right But understanding interactions between existing system calls and library functions Understands how threads affect system design Use it wisely and effectively Avoid common pitfalls and fallacies 2011/02 Shuo Chen (blog.csdn.net/Solstice) 4
  • 5. 11 essential Pthreads functions 11 out of 110+ pthreads functions 2 -> create and join threads 4 -> init/destroy, lock/unlock mutexes 5 -> init/destroy, wait/signal/broadcast condvars Think twice if you need more Some are okay, eg. once and key, maybe rwlock Some are bad, eg. cancel and kill, semaphores Check muduo/base for encapsulation in C++ http://code.google.com/p/muduo http://github.com/chenshuo/recipes click thread 2011/02 Shuo Chen (blog.csdn.net/Solstice) 5
  • 6. An asynchronous world Never assume the sequence of events without proper synchronization. Knows happens-before relation, memory visibility, etc. The effect of an interaction between two [thread]s must be independent of the speed at which it is carried out. --- Brinch Hansen 1973 2011/02 Shuo Chen (blog.csdn.net/Solstice) 6
  • 7. Standards and practices Although the latest official standards of C and C++ languages (C99 and C++03) do not say a word about process or thread We write multi-process and/or multi-threaded C/C++ programs in real life, as a real-world need We can’t wait it to be standardized, as standards usually fall behind practices for years btw, if there are not real life multi-threads programs , how do people what/how to standardize? We adhere to some de facto standards A lot simpler if we focus on one hardware and one OS 2011/02 Shuo Chen (blog.csdn.net/Solstice) 7
  • 8. Thread identifier on Linux Use pid_t as thread id, instead of pthread_t, on Linux pthread_tthid = pthread_self(), thid is opaque (uintptr_t) pid_ttid = ::gettid(), tid is task id, usually a small integer /proc/tid/, /proc/pid/task/tid/, ps, top all work fine How to implement gettid() efficiently? Thread local? gettid(2) is a syscall, but the output should never change getpid(2) caches the result, should gettid() do the same? What if fork(), will it caches the old value in child proc? How about pthread_atfork() to clear it up? Check muduo/base/Thread.cc for details 2011/02 Shuo Chen (blog.csdn.net/Solstice) 8
  • 9. Creation of threads A library should not create its own ‘background’ thread without prior informed consent Makes a program non-forkable Never create thread before main() Avoid creating thread in ctor of static or global object Breaks static objects constructing, eg. protobuf registering The number of threads created should be independentof system load, eg. # of connections, # of requests otherwise non-scalable Reuse threads, by assign multiple roles to it Doing IO and timer with muduoEventLoop class For simple task, do it within IO callbacks in IO threads 2011/02 Shuo Chen (blog.csdn.net/Solstice) 9
  • 10. Three ways of termination http://blog.csdn.net/program_think/archive/2009/03/14/3991107.aspx Natural death – return from thread function, good Suicide – call pthread_exit() Mudered – killed by pthread_cancel() Rule: let it die, never suicide or murder a thread Why? inherently deadlock-prone: no chance to unlock Design your program so that a thread can be waken up and safely exits For reference Java Thread.{stop, suspend and destroy} are deprecated Boost Threads doesn’t provide thread::cancel() 2011/02 Shuo Chen (blog.csdn.net/Solstice) 10
  • 11. pthread_cancel() and C++ In C, we have concept of ‘cancellation point’ In C++, pthread_cancel() throws an exception in that thread, helps unwinding objects on stack The exception must reach the outmost function, otherwise core dump: FATAL: exception not rethrown Aborted (core dumped) Always rethrow in catch(…) cause Ulrich Drepper “Cancellation and C++ Exceptions” Better: never cancel or kill a thread 2011/02 Shuo Chen (blog.csdn.net/Solstice) 11
  • 12. exit() is not thread safe in C++ exit() destructs static or global objects, (_exit() doesn’t) The destructor may try to hold a lock The caller function may have held the same lock already End up in a dead lock Check following code for an example of dead lock github.com/chenshuo/recipes/blob/master/thread/test/ExitDeadLock.cc How to quit a multi-threaded program safely? An irregular but simple solution: make a process killable, eg. p.29 blog.csdn.net/Solstice/archive/2010/10/19/5950190.aspx It’s not fault of exit(), but static or global objects Try to avoid static or global objects in C++, except for PODs 2011/02 Shuo Chen (blog.csdn.net/Solstice) 12
  • 13. Thread local __thread in g++ Thread safe by natural, unless escaped to other thread More efficient implementation, than pthread_key_t See “ELF Handling For Thread-Local Storage” In C++, must be initialized with constant-expression No __thread string t_obj("Chen Shuo"); No __thread string* t_obj = new string; Only __thread string* t_obj = NULL; More rules: http://gcc.gnu.org/onlinedocs/gcc/Thread_002dLocal.html Use pthread_key_t if you want auto destruction 2011/02 Shuo Chen (blog.csdn.net/Solstice) 13
  • 14. Use non-recursive mutex only A basic assumption of holding a mutex Once I lock it, I can modify the guarded object safely Which is not true for recursive mutex, eg. http://blog.csdn.net/Solstice/archive/2010/02/12/5307710.aspx#_Toc11928 Recursive mutexes by David Butenhof http://zaval.org/resources/library/butenhof1.html Recursive locks - a blessing or a curse?  http://www.thinkingparallel.com/2006/09/27/recursive-locks-a-blessing-or-a-curse/ 2011/02 Shuo Chen (blog.csdn.net/Solstice) 14
  • 15. Impacts of introducing threads Threading is a late patch to OS kernel Unix kernel and API formed in early 1970s First implementation of threads emerged in early 1990s Breaks lots of assumptions made during the 20 years Library functions with side effects must be revisited malloc/free, fread/fseekcan be made thread-safe with locks Functions that return or use static allocated space are not thread safe but may have thread-safe variants asctime_r, ctime_r, gmtime_r, rand_r, stderror_r, strtok_r errno is not an ‘extern int’, but a per-thread value extern int *__errno_location(void); #define errno (*__errno_location()) 2011/02 Shuo Chen (blog.csdn.net/Solstice) 15
  • 16. Thread safety of C library Individual system calls must be thread safe Be caution of interfering of same file descriptor from multiple threads Most of glibc library functions are thread safe nowadays Counterintuitively, Posix standards lists functions thatare not required to be thread safe, it's a black list. http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09 2.9.1 Thread-Safety : All functions defined by this volume of POSIX.1-2008 shall be thread-safe, except that the following functions need not be thread-safe. Notably, getenv/putenv/setenv/system() are not safe 2011/02 Shuo Chen (blog.csdn.net/Solstice) 16
  • 17. FILE* functions are thread safe Read ‘man flockfile’, but they are not composable, eg. fseek(), followed by fread() The file position may change during the course by a different thread Wrap with flockfile(FILE*) and funlockfile(FILE*) Same applies to lseek(2) and read(2), but how to lock? Use pread(2) instead, which doesn’t change the file offset In general, a function that calls two thread-safe functions is not guaranteed to be thread-safe Just like exception-safety, thread-safety is not composable 2011/02 Shuo Chen (blog.csdn.net/Solstice) 17
  • 18. Thread safety is not composable A solution works in single-threaded program may not apply to multi-threaded program. Any solution calls two or more thread safe function are not necessarily correct in multi-threaded program What’s the time in London now? Program runs in New York string oldTz = getenv("TZ"); // save TZ putenv("TZ=Europe/London"); tzset(); // set TZ to London struct tm localTimeInLN = *localtime(time(NULL)); setenv("TZ", oldTz.c_str(), 1); tzset(); // restore old TZ This code impacts localtime() in other threads Thread safe functions are not composable unless you carefully design the interface and interactions 2011/02 Shuo Chen (blog.csdn.net/Solstice) 18
  • 19. Thread safety of C++ std library Although not required by the standard, the de facto says Unshared objects are independent: Two threads can freely use different objects without any special action on the caller's part. We call it "same level as built-in types." This applies to STL containers like map, vector, string Pure functions are safe, eg. Most of STL algorithms. The global cin/cout objects are shared by threads, and are not thread safe. Moreover, they can't be made safe cout << a << b;  cout.operator<<(a).operator<<(b); Two function calls can be interrupted by another thread Use printf(3) instead, it's thread safe and atomic. Allocators must be thread safe, as they are shared 2011/02 Shuo Chen (blog.csdn.net/Solstice) 19
  • 20. Thread-Safe vs. Thread-Efficient printf(3) and malloc(3) are thread safe, but not necessarily efficient enough, esp. on multi-cores printf(3) locks FILE* stdout, synchronizes threads not good for multi-threaded logging, we need a better lib your default malloc(3) may not optimized for multi-threads and multi-cores it may lock global heap for each allocation try tcmalloc, Google's thread-cache malloc see Intel. Is your memory management multi-core ready? http://software.intel.com/en-us/blogs/2009/08/21/is-your-memory-management-multi-core-ready/ 2011/02 Shuo Chen (blog.csdn.net/Solstice) 20
  • 21. Operate one fd in one thread Although system calls of file descriptors are safe What if a thread close a fd when other thread is block reading it? What happens if a thread add a fd to epoll watch list while other thread is epoll_wait()ing it? What happens if two threads poll same fd, and find it readable simultaneously? What if two threads read the same TCP socket but each get partial data? How do you tell which part comes first? Rule: all operations on one file descriptor should happen in one thread, make your life a lot easier 2011/02 Shuo Chen (blog.csdn.net/Solstice) 21
  • 22. File descriptors in threads File descriptors are small integers, unlike HANDLE When create a new fd, kernel picks the lowest unused one Higher possibility of cross-talk, if careless, eg. A fd shared by two threads The first thread have just close()d it The second is about to read() it But a third thread happened to create a new fd with same id (the lowest available int reused) during the period What does the second thread read from? Any other impact? Solution: manage resource with RAII idiom And use the usual technique to manage object life cycles 2011/02 Shuo Chen (blog.csdn.net/Solstice) 22
  • 23. C++ and fork() A object could construct once but destruct twice int main() { Foofoo; // call 'Foo::Foo' fork(); // fork to two process // call 'Foo::~Foo' in parent *and* child processes } It might be a problem, if Foo owns some resource that is not inherited by child process Again, avoid static or global objects in C++ In child process, the object may not be properly initialized A global muduo::Timestamp startTime(now()) is wrong 2011/02 Shuo Chen (blog.csdn.net/Solstice) 23
  • 24. RAII and fork() fork() doesn't copy all state Open file descriptors are inherited by child process But the offset of file are independent The child does not inherit its parent's memory locks (mlock(2), mlockall(2)) record locks from its parent (fcntl(2)) timers from its parent (setitimer(2), alarm(2), timer_create(2)), and others So the RAII idiom may not work well in fork()ed process A RAII class that wraps timer_create/timer_delete in ctor/dtor may fail in child process after fork() Use pthread_atfork() as the last resort 2011/02 Shuo Chen (blog.csdn.net/Solstice) 24
  • 25. C++ and threads Use scoped lock guard only, check muduo/base/Mutex.h Don't allow exceptions to propagate across module boundaries don't let exception propagate out of the thread main function, catch all exceptions in the outer-most function But, rethrow the one of pthread_cancel(), as we said before Don't allow exceptions to propagate out of your callback, esp. callbacks from C library, eg. the init_routine registered to pthread_once() Better: don't use exception in C++ 2011/02 Shuo Chen (blog.csdn.net/Solstice) 25
  • 26. Threads and fork() The fork() model doesn’t fit well in threads A fundamental flaw of PosixOSes, as other threads disappear in child, the state is not consistent in child proc After fork a multi-threaded program you may only call async-signal-safe functions in child, as if in signal handler malloc() is not safe, other thread may hold the lock when fork()ing, and no chance to unlock in the new process So does printf(), pthread_* and others. The only safe way to use fork() in a multi-threaded program is calling exec() immediately in child process And make sure set close-on-exec flag on every file descriptors in parent process for security reasons. 2011/02 Shuo Chen (blog.csdn.net/Solstice) 26
  • 27. Signals and threads The whole Posix signal mechanism is a shit Only async-signal-safe functions can be called in signal handler, also called 'reentrant functions' Most of the functions are notasync-signal-safe, except those listed in Posix standards, so it's a white list http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03_03 'man 7 signal' to get the list on Linux None of pthread_* are not async-signal-safe, you can't notify a condvar or lock a mutex in signal handler Surprisely, gettimeofday(2) is not async-signal-safe 2011/02 Shuo Chen (blog.csdn.net/Solstice) 27
  • 28. Deal with signals in MT programs Rule 1: do not use signal don't use it as IPC, eg. SIGUSR1, SIGUSR2, SIGINT, SIGHUP don't use library functions built upon signals, eg. alarm, sleep, usleep, timer_create, etc. Rule 2: when you absolutely need, convert an async signal to synchronous file descriptor readable event use signalfd in high Linux kernel version Normally, the set of signals to be received via the file descriptor should be blocked using pthread_sigmask(3), to prevent the signals being handled according to their default dispositions. or open a pipe(2), write(2) one byte in signal handler, and read(2) or poll(2) it in main thread 2011/02 Shuo Chen (blog.csdn.net/Solstice) 28
  • 29. Other resources http://pubs.opengroup.org/onlinepubs/9699919799/ http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them http://www.linuxprogrammingblog.com/all-about-linux-signals http://www.cppblog.com/lymons/archive/2008/06/01/51838.html Seven posts in http://www.cppblog.com/lymons/category/9446.html 2011/02 Shuo Chen (blog.csdn.net/Solstice) 29
  • 30. To be continued Essential of non-blocking network programming in C++ Birth of a reactor – design and implementation of Muduo 2011/02 Shuo Chen (blog.csdn.net/Solstice) 30
  • 31. Avoid static or global objects Except for PODs 2011/02 Shuo Chen (blog.csdn.net/Solstice) 31

Editor's Notes

  1. http://boost.cppll.jp/BDTJ_1_30/libs/thread/doc/rationale.html#Events
  2. http://download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.htmlhttp://boost.cppll.jp/BDTJ_1_30/libs/thread/doc/faq.html
  3. http://udrepper.livejournal.com/21541.html
  4. http://people.redhat.com/drepper/tls.pdf
  5. random_shuffle
  6. http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them
  7. http://www.linuxprogrammingblog.com/all-about-linux-signalshttp://www.cppblog.com/lymons/archive/2008/06/01/51838.html