国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

Linux 線程 條件變量

2024-06-28 13:25:06
字體:
來源:轉載
供稿:網友
linux 線程 條件變量一:條件變量  直接上最基本的兩個函數,先抓主要矛盾:
//等待條件int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restric mutex);1:把調用線程放到所等待條件的線程列表上2:對傳進來已經加過鎖的互斥量解鎖3:線程進入休眠狀態等待被喚醒注:1、2步為原子操作//通知條件int pthread_cond_signal(pthread_cond_t *cond);1:通知指定條件已經滿足2:等待線程重新鎖定互斥鎖3:等待線程需要重新測試條件是否滿足



二:生產者消費者   下面是一個多線程,生產者消費者問題,一個隊列放暫存的數據:
 1 #include <iostream> 2 #include <queue> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <pthread.h> 6  7 using std::cout; 8 using std::endl; 9 using std::queue;10 11 #define N 10012 #define ST 1013 14 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;15 pthread_cond_t ready = PTHREAD_COND_INITIALIZER;16 17 queue<int> que;18 19 void* threadPRoducer(void* arg)20 {21     while(true)22     {23         sleep(rand() % ST);24         25         cout << "Produce try in.../n";26         pthread_mutex_lock(&lock);27         cout << "Produce in!/n";28         int source = rand() % N;29         cout << "Produce " << source << endl;30         que.push(source);31         pthread_mutex_unlock(&lock);32         cout << "Produce out/n";33         34         pthread_cond_signal(&ready);35     }36 }37 38 void* threadConsumer(void* arg)39 {40     while(true)41     {42         sleep(rand() % ST);43         44         cout << "Consum try in.../n";45         pthread_mutex_lock(&lock);46         cout << "Consum in!/n";47         while(que.empty())48         {49             pthread_cond_wait(&ready, &lock);50             cout << "Consum from sleep/n";51         }52         cout << "Consum " << que.front() << endl;53         que.pop();54         pthread_mutex_unlock(&lock);55         cout << "Consum out/n/n";56     }57 }58 59 int main(void)60 {61     pthread_t tProducer, tConsumer;    62     pthread_create(&tProducer, NULL, threadProducer, NULL);63     pthread_create(&tConsumer, NULL, threadConsumer, NULL);64     65     pthread_join(tProducer, NULL);66     pthread_join(tConsumer, NULL);67 68     exit(0);69 }
生消

看到倒數的三四行,消費者進去了,發現沒有數據了,則睡眠了,然后生產者進去生產了。


三:打印的例子  下面是一個多線程的小例子,線程1打印非3的倍數,線程2打印3的倍數:
#include <iostream>#include <stdlib.h>#include <unistd.h>#include <pthread.h>using std::cout;using std::endl;pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t ready = PTHREAD_COND_INITIALIZER;int data = 0;void* threadProducer(void* arg){    int i;    for(i = 1; i < 22; i++)    {            sleep(1);            if(i % 3 != 0)        {            cout << "thread1:" << i << endl;        }        else        {            pthread_mutex_lock(&lock);            data = i;            pthread_mutex_unlock(&lock);                        pthread_cond_signal(&ready);        }        }}void* threadConsumer(void* arg){    while(true)    {        pthread_mutex_lock(&lock);        while(data == 0)    //no data            pthread_cond_wait(&ready, &lock);        cout <<"thread2:" << data << endl;        if(data == 21)            break;        else            data = 0;    //empty data        pthread_mutex_unlock(&lock);    }}int main(void){    pthread_t tProducer, tConsumer;        pthread_create(&tProducer, NULL, threadProducer, NULL);    pthread_create(&tConsumer, NULL, threadConsumer, NULL);        pthread_join(tProducer, NULL);    pthread_join(tConsumer, NULL);    exit(0);}
3打印

  程序大致這樣:線程1中的循環,如果i不是3的倍數就自己打印了,如果是的話,把這個數放到一個地方(由于這個地方可以被線程2發現,所以要加鎖訪問),然后喚醒等待數據的線程2(如果線程2還沒有在等待,那么這個喚醒則丟失,這是個bug,見下),線程2被喚醒后,消費了這個3的倍數,清空數據區。

  上面提到,如果喚醒線程2的消息沒有被收到,則bug??聪旅娴拇a,也就多了38一行,讓線程2睡了一會,就在它睡覺的那么一會,線程1把3的倍數往那里一扔就走了,自己再繼續下兩個不是3倍數的數字,這就直接輸出了下面兩個數字,又到了3倍數,又扔過去覆蓋了之前數字:
 1 #include <iostream> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <pthread.h> 5  6 using std::cout; 7 using std::endl; 8  9 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;10 pthread_cond_t ready = PTHREAD_COND_INITIALIZER;11 12 int data = 0;13 14 void* threadProducer(void* arg)15 {16     int i;17     for(i = 1; i < 22; i++)18     {    19         sleep(1);20     21         if(i % 3 != 0)22         {23             cout << "thread1:" << i << endl;24         }25         else26         {27             pthread_mutex_lock(&lock);28             data = i;29             pthread_mutex_unlock(&lock);30             31             pthread_cond_signal(&ready);32         }    33     }34 }35 36 void* threadConsumer(void* arg)37 {38     sleep(20);39     while(true)40     {41         pthread_mutex_lock(&lock);42         while(data == 0)    //no data43             pthread_cond_wait(&ready, &lock);44         cout <<"thread2:" << data << endl;45         if(data == 21)46             break;47         else48             data = 0;    //empty data49         pthread_mutex_unlock(&lock);50     }51 }52 53 int main(void)54 {55     pthread_t tProducer, tConsumer;    56     pthread_create(&tProducer, NULL, threadProducer, NULL);57     pthread_create(&tConsumer, NULL, threadConsumer, NULL);58     59     pthread_join(tProducer, NULL);60     pthread_join(tConsumer, NULL);61 62     exit(0);63 }
bug




四:總結    從上面可以總結出下面的條件變量的生產者消費者代碼模型:
//下面是生產者pthread_mutex_lock(&lock);    //加鎖訪問臨界區/*在這里生產數據*/pthread_mutex_unlock(&lock);    //解鎖    pthread_cond_signal(&ready);    //通知消費者//下面是消費者pthread_mutex_lock(&lock);    //加鎖訪問臨界區while(沒有待消費數據)        pthread_cond_wait(&ready, &lock);    //睡在這里,等待被喚醒/*被叫醒了,在這里消費數據*/pthread_mutex_unlock(&lock);    //解鎖

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武乡县| 会昌县| 韩城市| 青龙| 准格尔旗| 瑞丽市| 垣曲县| 兴山县| 金平| 阿鲁科尔沁旗| 息烽县| 洱源县| 灵川县| 岫岩| 汨罗市| 建水县| 郑州市| 新兴县| 阜平县| 平果县| 临汾市| 武邑县| 平顶山市| 扎赉特旗| 达尔| 舒兰市| 永顺县| 卢氏县| 贺兰县| 南京市| 溧阳市| 天祝| 苍山县| 龙海市| 睢宁县| 江西省| 张家口市| 马尔康县| 民权县| 滦平县| 绥棱县|