Example 11-1
Is the result of running on Ubuntu12.04 inconsistent with the description in the book?
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M00/4B/8D/wKioL1QuXwCy0R_rAABOITQM-aQ678.jpg "title=" instance 11-1 "alt=" Wkiol1quxwcy0r_raaboitqm-aq678.jpg "/>
From the PID point of view these two threads belong to the same process, and the thread ID is also a pointer form, Google learned that the book is about the previous Linuxthreads implementation, now Linux uses NPTL thread.
Reference: Comparison of Linux threading models: Linuxthreads and NPTL
Exercise 11.4
Before I answer this question, I think I need to figure out the relationship between "mutex" and "condition variable". Because the book said that the two are generally used in support.
Consider the following scenario:
Both child thread B and child thread C are waiting for the main thread A to send a signal through the same condition variable cond, and if the test condition is false, the two threads will continue to block hibernation. However, there is a time window between the judgment condition and sleep, if the CPU switches to the main line a when the two strands Cheng gang the condition is false but does not enter the blocking sleep, thread A makes the condition become true. Then, when the CPU switches the B and C threads, the thread still goes into hibernation (and misses the time when the condition is true, and may no longer wait for the condition to be true). This means that there is a time window between the thread check condition variable and the move into hibernation wait condition change. There is a competition here.
We know that mutex can be used to solve the competition problem above, so "the condition variable itself is protected by" mutex ".
Since judgment and sleep are protected by mutual exclusion to become an atomic operation, other threads that change conditions should modify the condition in a consistent manner, meaning that other threads must first lock the mutex before changing the condition state. (If the modification is not protected by a mutex, then it is meaningless to judge and hibernate to use mutex to protect it.) Because other threads can still change the condition in the void of two operations. However, if the modify operation also uses the mutex amount. Because of the lock before the judgment and sleep. Then the modification operation can only wait until the judgment fails and the hibernation two operation is completed before it can be modified.
The approximate process is as follows:
Thread b:lock-> judgment condition (false)->wait (Hibernate &unlock)->lock-> perform the appropriate action
Thread a:lock-> make the condition true->unlock-> send a signal
Look at a concrete example.
#include <stdio.h> #include <pthread.h>unsigned int test_signal = 0; pthread_mutex_t mutex = pthread_mutex_initializer;pthread_cond_t cond = Pthread_cond_initializer;void *thread1 (Void *arg) { pthread_mutex_lock (& Mutex); while (1000 != test_signal) { pthread_cond_wait (&cond,&mutex); } pthread_mutex_unlock (&mutex); printf ("This is thread 1\n "); pthread_exit ((void *) 0);} Void *thread2 (Void *arg) { pthread_mutex_lock (&mutex); while (1000 != test_signal) &NBSP;&NBSP;&NBSP;&NBSp { pthread_cond_wait (&cond,&mutex); } pthread_mutex_unlock (&mutex); printf ("This is thread 2\n "); pthread_exit ((void *) 0);} Int main (void) { pthread_t tid1, tid2; pthread_ Create (&tid1, NULL, thread1, (void *) 0); pthread_create (& tid2, null, thread2, (void *) 0); while (1) { pthread_mutex _lock (&mutex); test_signal++; pthread_mutex_unlock (& Mutex); if (1000 == test_signal) { pthread_cond_broadcast (&cond); break; } } pthread_join (Tid1,null); pthread_join (Tid2, NULL); pthread_cond_destroy (&cond); pthread_mutex_destroy ( &mutex); exit (0);}
OK, now back to the question itself, both of these steps are actually possible but there are some deficiencies.
Step A:
(1) The mutex locking (Pthread_mutex_lock)
(2) The condition of changing the protection of mutex amount. (corresponding to the above example is the test_signal++ in the main thread
Operation
(3) Send a signal to a thread waiting for a condition (pthread_cond_broadcast)
(4) Unlock the Mutex (Pthread_mutex_unlock)
That is, the main thread sends the conditional signal before unlocking. So that is the main thread to send a signal or hold a lock, when the child thread received a signal will end hibernation but said Pthread_cond_wait return will be the lock again, but the main thread has not released the lock, so it will cause the child thread to receive a signal to start running but immediately blocked.
Step b:
(1) The mutex locking (Pthread_mutex_lock)
(2) The condition of changing the protection of mutex amount. (corresponding to the above example is the i++ operation in the main thread)
(3) Unlock the Mutex (Pthread_mutex_unlock)
(4) Send a signal to a thread waiting for a condition (pthread_cond_broadcast)
The main thread sends a signal after releasing the lock. This is what the above example does. But there's also a problem. But when the lock is released, other threads are likely to get a lock before sending the signal and modify the test_signal to cause the condition to not be established again, but the main thread is unaware, causing the message to still be sent to the child thread. The child thread considers the condition to be satisfied from waking to start running, but the condition is not satisfied at this time.
So in the example above,
while (test_signal! =) {pthread_cond_wait (&cond,&mutex);}
It is necessary to let the child thread wake up again to determine whether the condition is established or not, so that the above problem can be avoided.
This article is from the "Two Bears blog" blog, please be sure to keep this source http://t19880825.blog.51cto.com/9445110/1560542
Apue Reading notes-11th chapter thread