別のミューテックスを使用すると、条件変数ではなく、ロックを待つのに使用されています。条件変数は、自動的に特定の特殊な状況になるまでスレッドをブロックするために使用されます。同時に、通常の条件変数とミューテックス。
条件変数我々はいくつかの条件が発生したために待って眠ることができるようにします。条件変数は、スレッド間の二つの主要なアクションを備え、同期するためのメカニズムの共有グローバル変数を使用することです:ハング「の条件が満たされた状態変数である」待つスレッドを、別のスレッド「の条件が成立する」ように(与えられた条件が満たされています信号)。
条件を検出することは、保護ミューテックスの下で行われます。条件がfalseの場合、スレッドは自動的にブロックされ、ミューテックス待ち状態変化を解除しています。別のスレッドが条件を変更した場合、それが関連する状態変数への信号、またはそれがミューテックス、条件の再評価を回復するためのウェイクアップ複数のスレッドが待っています。2つのプロセスが読み書きメモリを共有している場合は、条件変数は、これら2つのプロセス間のスレッドの同期を実装するために使用することができます。
これは、最初の条件変数を使用する前に初期化する必要があります。単一のステートメントとして条件変数の初期化を生成することができる:pthread_cond_t my_condition = PTHREAD_COND_INITIALIZER;(プロセス間通信のためのスレッド)。pthread_cond_init動的初期化機能を利用することができます。
状態変数は、2つの部分に分割される:条件および変数条件自体は、相互排他ロックミューテックススレッドによって保護されなければならない最初のスレッド間で共有されるグローバル変数を同期させるメカニズムであった使用状態の条件を変更する前に...
関連する次のように機能します。
1 int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);
2 int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
3 int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime);
4 int pthread_cond_destroy(pthread_cond_t *cond);
5 int pthread_cond_signal(pthread_cond_t *cond);
6 int pthread_cond_broadcast(pthread_cond_t *cond); //解除所有线程的阻塞
簡単な説明:
(1)初期設定の.init()またはpthread_cond_t COND = PTHREAD_COND_INITIALIER;属性がNULLに設定されている
(2)の条件が満たさ.pthread_waitで待機し、pthread_timewait.wait()はロックを解除し、待ち条件変数をブロックすることは事実である
TIMEWAIT()を設定待ち時間、まだETIMEOUT(ロックはその一つだけのスレッドの待機を保証)を返す、信号
(3)起動条件変数:pthread_cond_signalを、pthread_cond_broadcastの(すべての待機中のスレッドを起動する)
(4)クリア条件変数:破壊を、無線待機中のプロセスを、そうでない場合はEBUSY
詳細な説明
1.初期化:
データ型pthread_cond_t条件変数が使用されている、二つの方法が含まれ、使用する前に初期化する必要があります。
静的:あなたは静的に割り当てられた条件変数に定数PTHREAD_COND_INITIALIZERを置くことができます。
ダイナミック:メモリ空間のリリースは動的な条件変数である前に、てpthread_cond_init機能、使用pthread_cond_destroyは、掃除をして。
#include <pthread.h>
int pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t *cond);
成功则返回0, 出错则返回错误编号.
pthread_cond_init attrのパラメータがNULLの場合は、デフォルトの条件変数属性を作成します。デフォルト以外の後に議論を。
2.待ち条件:
#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restric mutex);
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict timeout);
成功则返回0, 出错则返回错误编号.
これらの2つの関数は待っていると、タイムアウトを待ってブロックされている。条件がtrueになる待ち待ちコン、ミューテックスに渡され、pthread_cond_waitの保護のための条件は、呼び出し側は関数にロックされたミューテックスを渡す。関数を呼び出すスレッドに状態を待機中のスレッドのリスト上に置かれ、次いで、ミューテックスのロックが解除されて、これら二つの操作がアトミックである。このような閉じた状態チェック及びチャネル状態のためにスリープ状態を待機中にスレッドであろうが、これら二つの動作の時間の間で変化するようにスレッド条件の変更は、見逃すことはありません。
リターンをpthread_cond_waitのとき、mutexは再びロックされています。
3.通知条件:
#include <pthread.h>
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
成功则返回0, 出错则返回错误编号.
これらの2つの関数は、スレッドが満たされている通知するために使用されている。これらの関数は、スレッド又は条件へ信号を送るとしても知られている。それは注意しなければならない、と呼ばれ、将来の状態で条件を変更するスレッド信号を与えなければなりません。
条件変数同期インスタンス - インスタントラーメンのコントロールの販売
// pthread_cond_t cond; 定义一个条件变量
14 // pthread_cond_init; 初始化条件变量
15 // pthread_cond_destroy 销毁
16 // pthread_cond_wait 等待
17 // pthread_cond_signal 通知 等待在条件变量 上的线程
18
19
20
21
22 #include<stdio.h>
23 #include<unistd.h>
24 #include<pthread.h>
25 #include<stdlib.h>
26
27 int g_judge=0; //0代表没有方便面 1代表有方便面
28 pthread_mutex_t mutex;
29 pthread_cond_t full;
30 pthread_cond_t empty;
31
32
W> 33 void* sale_noodles(void* arg)
34 {
35
36 while(1)
37 {
38 // usleep(300);
39
40 pthread_mutex_lock(&mutex);
41
42 while(g_judge==1)
//先解锁
47 //集合了 解锁+ 休眠+ 被唤醒后加锁 的原子操作
48 pthread_cond_wait(&full,&mutex); //这个 mutex 有什么用? ---> ++g_judge不是一个原子操作,涉及到对临界资源的修改,多对多情况> 下不安全
49
50
51 }
52 printf("product one noodle\n");
53 g_judge++;
54 //因为买方便面一直在wait死等,所以还需要通知一下
55 pthread_cond_signal(&empty);
E> 56 pthread_mutex_unlock(mutex);
57
58 }
59
60
61 return NULL;
62
63 }
64
65
66
E> 67
68
69
70
E> 71 void* buy_noodles(void* arg)
72 {
73
74
75
76
77 while(1)
{
pthread_mutex_lock(&mutex); //这块为什么加锁,涉及到对临界资源的访问
80
81 //如果没有方便面,就要等待
82 while(g_judge==0) //必须得用 while 判断 因为有很多线程不停的判断
83 {
84 //int pthread_cond_wait( ... )
85 pthread_cond_wait(&empty,&mutex); //解锁 和 挂起等待 必须是一个原子操作 ,否则不安全 && 完成之后如果被唤醒会重新尝试加锁
86
87
88
89 }
90
91
92 printf("eat one noodle~~~\n");
93 g_judge--;
94 pthread_cond_signal(&full);
95 pthread_mutex_unlock(&mutex);
96
97 }
98
99
100 return NULL;
101
102 }
103
int main()
115 {
116
117 pthread_cond_init(&full,NULL);
118 pthread_cond_init(&empty,NULL);
119 pthread_mutex_init(&mutex,NULL);
120
121 pthread_t tid1,tid2;
122 pthread_create(&tid1,NULL,sale_noodles,NULL);
E>123 pthread_create(&tid2,NULL,buy_noodles,NULL);
124
125 pthread_join(tid1,NULL);
126 pthread_join(tid2,NULL);
127
128 pthread_mutex_destroy(&mutex);
129 pthread_cond_destroy(&full);
130 pthread_cond_destroy(&empty);
131
132 }
注意:私たちは、空と完全な2つの条件変数を作成する必要があります。買い手と売り手の時間を待って、その条件変数を待っています。同じ条件および他の変数に同時に買い手と売り手の両方の場合は、バグがマルチスレッドの場合に発生しやすくなります。もう一つのポイントは、パラメータがあるということです、それはのコレクションですので、なぜmutexをpthread_cond_waitのロック解除+スリープ+ウェイクアッププラスした後ロックアトミック操作を。
//集合了 解锁+ 休眠+ 被唤醒后加锁 的原子操作
pthread_cond_wait(&full,&mutex);