可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
this is my first pthread program, and I have no idea why the printf statement get printed twice in child thread:
int x = 1; void *func(void *p) { x = x + 1; printf("tid %ld: x is %d\n", pthread_self(), x); return NULL; } int main(void) { pthread_t tid; pthread_create(&tid, NULL, func, NULL); printf("main thread: %ld\n", pthread_self()); func(NULL); }
Observed output on my platform (Linux 3.2.0-32-generic #51-Ubuntu SMP x86_64 GNU/Linux):
1. main thread: 140144423188224 tid 140144423188224: x is 2 2. main thread: 140144423188224 tid 140144423188224: x is 3 3. main thread: 139716926285568 tid 139716926285568: x is 2 tid 139716918028032: x is 3 tid 139716918028032: x is 3 4. main thread: 139923881056000 tid 139923881056000: x is 3 tid 139923872798464tid 139923872798464: x is 2
for 3, two output lines from the child thread
for 4, the same as 3, and even the outputs are interleaved.
回答1:
It looks like the real answer is Michael Burr's comment which references this glibc bug: https://sourceware.org/bugzilla/show_bug.cgi?id=14697
In summary, glibc does not handle the stdio buffers correctly during program exit.
回答2:
Threading generally occurs by time-division multiplexing. It is generally in-efficient for the processor to switch evenly between two threads, as this requires more effort and higher context switching. Typically what you'll find is a thread will execute several times before switching (as is the case with examples 3 and 4. The child thread executes more than once before it is finally terminated (because the main thread exited).
Example 2: I don't know why x is increased by the child thread while there is no output.
Consider this. Main thread executes. it calls the pthread and a new thread is created.The new child thread increments x. Before the child thread is able to complete the printf statement the main thread kicks in. All of a sudden it also increments x. The main thread is however also able to run the printf statement. Suddenly x is now equal to 3. The main thread now terminates (also causing the child 3 to exit). This is likely what happened in your case for example 2.
Examples 3 clearly shows that the variable x has been corrupted due to inefficient locking and stack data corruption!!
For more info on what a thread is.
Link 1 - Additional info about threading
Link 2 - Additional info about threading
Also what you'll find is that because you are using the global variable of x, access to this variable is shared amongst the threads. This is bad.. VERY VERY bad as threads accessing the same variable create race conditions and data corruption due to multiple read writes occurring on the same register for the variable x. It is for this reason that mutexes are used which essentially create a lock whilst variables are being updated to prevent multiple threads attempting to modify the same variable at the same time. Mutex locks will ensure that x is updated sequentially and not sporadically as in your case.
See this link for more about Pthreads in General and Mutex locking examples.
Pthreads and Mutex variables
Cheers,
Peter
回答3:
Hmm. your example uses the same "resources" from different threads. One resource is the variable x, the other one is the stdout-file. So you should use mutexes as shown down here. Also a pthread_join at the end waits for the other thread to finish its job. (Usually a good idea would also be to check the return-codes of all these pthread... calls)
#include <pthread.h> #include <stdio.h> int x = 1; pthread_mutex_t mutex; void *func(void *p) { pthread_mutex_lock (&mutex); x = x + 1; printf("tid %ld: x is %d\n", pthread_self(), x); pthread_mutex_unlock (&mutex); return NULL; } int main(void) { pthread_mutex_init(&mutex, 0); pthread_t tid; pthread_create(&tid, NULL, func, NULL); pthread_mutex_lock (&mutex); printf("main thread: %ld\n", pthread_self()); pthread_mutex_unlock (&mutex); func(NULL); pthread_join (tid, 0); }