線程條件控制實現線程的同步

與條件變量相關API
? ??????條件變量是線程另一可用的同步機制。條件變量給多個線程提供了一個會合的場所。條件變量與互斥量一起使用時,允許線程以無競爭的方式等待特定的條件發生。

? ??????條件本身是由互斥量保護的。線程在改變條件狀態前必須首先鎖住互斥量,其他線程在獲得互斥量之前不會察覺到這種改變,因為必須鎖定互斥量以后才能計算條件。

? ??????條件變量使用之前必須首先初始化,pthread_cond_t數據類型代表的條件變量可以用兩種方式進行初始化,可以把常量? ??????PTHREAD_COND_INITIALIZER賦給靜態分配的條件變量,但是如果條件變量是動態分配的,可以使用pthread_cond_destroy函數對條件變量進行去除初始化(deinitialize)。
1. 創建及銷毀條件變量

#include <pthread.h>
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t*restrict cond);
// 返回:若成功返回0,否則返回錯誤編號

除非需要創建一個非默認屬性的條件變量,否則pthread_cont_init函數的attr參數可以設置為NULL。cond參數是條件也要進行定義和初始化
2. 等待

#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);//這個是立即返回
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);//這個是等待一段時間后返回
// 返回:若成功返回0,否則返回錯誤編號

? ??????pthread_cond_wait等待條件變為真。如果在給定的時間內條件不能滿足,那么會生成一個代表一個出錯碼的返回變量。傳遞給pthread_cond_wait的互斥量對條件進行保護,調用者把鎖住的互斥量傳給函數。函數把調用線程放到等待條件的線程列表上,然后對互斥量解鎖,這兩個操作都是原子操作。這樣就關閉了條件檢查和線程進入休眠狀態等待條件改變這兩個操作之間的時間通道,這樣線程就不會錯過條件的任何變化。pthread_cond_wait返回時,互斥量再次被鎖住。

? ??????pthread_cond_timedwait函數的工作方式與pthread_cond_wait函數類似,只是多了一個timeout。timeout指定了等待的時間,它是通過timespec結構指定。
3. 觸發

#include <pthread.h>
int pthread_cond_signal(pthread_cond_t*restrict    cond);
int pthread_cond_broadcast(pthread_cond_t *restrict cond);
// 返回:若成功返回0,否則返回錯誤編號

這兩個函數可以用于通知線程條件已經滿足。pthread_cond_signal函數將喚醒等待該條件的某個線程,而pthread_cond_broadcast函數將喚醒等待該條件的所有進程。

注意一定要在改變條件狀態以后再給線程發信號。
  
代碼示例

#include<stdio.h>
#include<pthread.h>
#include <stdlib.h>
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);int g_data=0;//pthread_mutex_t mutex;
pthread_cond_t cond;void*func1(void *arg)
{static cnt=0;printf("t1 :%ld thread is created\n",(unsigned long)pthread_self());printf("t1:param is %d\n",*((int*)arg));while(1){pthread_cond_wait(&cond,&mutex);printf("t1 over==============================\n");printf("t1 :%d\n",g_data);g_data=0;sleep(1);if(cnt++==10){exit(1);}}}void*func2(void *arg)
{printf("t2 :%ld thread is created\n",(unsigned long)pthread_self());
printf("t2:param is %d\n",*((int*)arg));while(1){printf("t2 printf is %d\n",g_data);pthread_mutex_lock(&mutex);g_data++;if(g_data==3){pthread_cond_signal(&cond);}pthread_mutex_unlock(&mutex);sleep(1);}pthread_mutex_unlock(&mutex);
}int main()
{int ret;int param=100;pthread_t t1;pthread_t t2;pthread_mutex_init(&mutex,NULL);pthread_cond_init(&cond,NULL);ret=pthread_create(&t1,NULL,func1,(void*)&param);if(ret==0){//      printf("main:create t1 success\n");}ret=pthread_create(&t2,NULL,func2,(void*)&param);if(ret==0){
//      printf("main:create t2 success\n");}
//      printf("main : %ld \n",(unsigned long)pthread_self());pthread_join(t1,NULL);pthread_join(t2,NULL);pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);return 0;
}
//其中func1中的cnt是測試用的
以下代碼可以用試:
CLC@Embed_Learn:~/xiancheng$ gcc demo8.c -lpthread -odemo8
CLC@Embed_Learn:~/xiancheng$ vi text1.c
CLC@Embed_Learn:~/xiancheng$ ./a.out 10 >>test.ret.txt &(其中>>表示將運行的結果追加到test.ret.txt中     &表示在后臺運行)
[1] 21313(這是進程的ID號)

初始化

pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
//靜態初始化
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
//動態初始化

參考博文:https://www.cnblogs.com/xiehongfeng100/p/4620852.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/272478.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/272478.shtml
英文地址,請注明出處:http://en.pswp.cn/news/272478.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

自定義能夠for each的類,C#,Java,C++,C++/cli的實現方法

自定義類能夠被for each&#xff0c;應該算是個老生常談的話題了&#xff0c;相關的資料都很多&#xff0c;不過這里整理總結主流語言的不同實現方式&#xff0c;并比較部分細節上的差異。 第一種語言&#xff0c;也是實現起來最簡單的Java語言。在Java里&#xff0c;要被for e…

SQL Server 2008 R2:快速清除日志文件的方法

本例&#xff0c;快速清理“students”數據庫的日志&#xff0c;清理后日志文件不足1M。USE [master] GO ALTER DATABASE students SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE students SET RECOVERY SIMPLE GO USE students GO--此處需要注意&#xff…

linux網絡編程之字節序

進程間通信 特點&#xff1a;依賴于內核&#xff0c;造成缺陷——無法實現多機通信。 網絡編程 地址&#xff1a;由IP地址和端口號構成&#xff0c;端口號用來判斷客戶端接入哪個服務器。 數據的交流&#xff1a;涉及到協議&#xff08;http&#xff0c;tcp&#xff0c;udp&…

Oracle查看表空間和表空間中的對象

select * from user_tables;--查詢所有用戶表 select username,default_tablespace from user_users;--查詢當前表空間select tablespace_name from dba_tablespaces;--查詢所有表空間select tablespace_name, sum(bytes)/1024/1024 from dba_data_files group by tablespace_n…

C#中DateTime.Ticks屬性及Unix時間戳轉換

DateTime.Ticks&#xff1a;表示0001 年 1 月 1 日午夜 12:00:00 以來所經歷的 100 納秒數&#xff0c;即Ticks的屬性為100納秒&#xff08;1Ticks 0.0001毫秒&#xff09;。Unix時間戳&#xff1a;是從1970年1月1日&#xff08;UTC/GMT的午夜&#xff09;開始所經過的秒數&am…

WebBrowser控件的常用方法、屬性和事件

1. 屬性屬性說明Application如果該對象有效&#xff0c;則返回掌管WebBrowser控件的應用程序實現的自動化對象(IDispatch)。如果在宿主對象中自動化對象無效&#xff0c;這個程序將返回WebBrowser 控件的自動化對象Parent返回WebBrowser控件的父自動化對象&#xff0c;通常是一…

二維碼高亮

// 二維碼高亮。http://blog.sina.com.cn/s/blog_a843a8850102uy6w.html 轉載于:https://www.cnblogs.com/muyushifang07/p/5114667.html

socket 網絡 編程

網絡編程場景 自己是客戶端站在5棟樓前&#xff0c;自己要找到5棟樓中的一座并進入某一間房間&#xff0c;這時第二座樓上有人在用漢語&#xff08;tcp/udp&#xff09;說話,我的ip地址&#xff08;樓號&#xff09;是…&#xff0c;我的端口號&#xff08;房間號&#xff09;是…

7個免費的Linux FTP客戶端工具

在Dropbox、YouSendIt、idrive以及許多這樣云存儲和共享工具的幫助下&#xff0c;我們在互聯網上發送和共享大型文件變得容易起來。所有這些網站都可以幫助你在互聯網上傳送文件&#xff0c;但如果你要分享龐大的數據&#xff0c;這依然是很復雜的事情。所以&#xff0c;你需要…

樹莓派的幾種登錄方式及樹莓派的網絡配置

&#xff08;1&#xff09;HDMI 視頻線 連接到顯示器 &#xff08;2&#xff09;串口 設備破解&#xff1a; 默認情況下,樹莓派的串口和藍牙連接&#xff0c;把串口用來數據通信。 修改系統配置&#xff0c;啟用串口登錄樹莓派 1.打開SD卡根目錄的"config.txt"文件…

C語言之常量與變量

1.常量 1.1整型常量:短整型(short int),整型(int),長整型(long int).短整型和長整型都可省慮后面的int,三者唯一的區別就是內存大小的區別,從小到大依次為short < int < long. int a;short int b;long int c;  printf("%d,%d",a,b);  printf("%ld&quo…

【收集】11款Linux數據恢復工具

如果你使用的是Linux操作系統&#xff0c;那么你一定想知道一旦硬盤崩潰的話又該如何保存和恢復數據。其實&#xff0c;現在有很多Linux數據恢復工具可以讓我們擺脫數據安全的困擾。小編已經為各位準備好了一些最好的Linux數據恢復工具&#xff0c;歡迎大家品鑒。KnoppixKnoppi…

VIM更新

1、可以用以下指令 sudo apt-get install vim2、默認的是國外的源&#xff0c;apt-get 安裝失敗的時候&#xff0c;我們更換成國內的源。 &#xff08;1&#xff09; 編輯sources.list 打開終端輸入 sudo nano /etc/apt/sources.list用#注釋或直接刪除原有的內容&#xff0c…

svn 常用操作命令

檢出svn co svn://xxxxx/svn/ios --username jm --password 123 通常情況下&#xff0c;命令svn add *會忽略所有已經在版本控制之下的目錄&#xff0c;有時候&#xff0c;你會希望添加所有工作拷貝的未版本化文件&#xff0c;包括那些隱藏在深處的文件&#xff0c;可以使用svn…

8款適合Linux用戶使用的數據庫管理工具

從內容管理系統到簡單的表格&#xff0c;數據庫是每一個開發項目的一部分。這就是為什么開發者們如此強調使用正確類型的數據庫工具。下面這些可能對您有所幫助&#xff01;1. AutotablaAutotabla是一個你的程序的SQL數據表的CGI管理界面。只需要提供你數據庫架構的XML描述&…

linux庫引入之分文件編程

分文件編程好處 將main函數和其他功能性函數放在不同的文件中&#xff0c;分模塊的編程思想&#xff0c;分工明確&#xff0c;查找錯誤比較容易&#xff0c;責任可以劃分清楚&#xff0c;程序也方便調試&#xff0c;并且主函數比較簡潔。 將文件從同一目錄下的另一個文件夾拷貝…

為什么Chrome瀏覽器特愛吃內存

微軟用慣用的手法——改名——給 IE 被黑的一生畫上了句號。還好&#xff0c;它在技術段子圈里早就有了接班人&#xff1a;Chrome。Chrome 很好很強大&#xff0c;速度極快、功能很多。但同時它也是你的電腦內存不足或者耗電太快的罪魁禍首。沒辦法&#xff0c;Chrome 太愛吃內…

nyoj--120--校園網絡(scc+縮點)

校園網絡 時間限制&#xff1a;3000 ms | 內存限制&#xff1a;65535 KB難度&#xff1a;5描述南陽理工學院共有M個系&#xff0c;分別編號1~M,其中各個系之間達成有一定的協議&#xff0c;如果某系有新軟件可用時&#xff0c;該系將允許一些其它的系復制并使用該軟件。但該允…

SQL的四種連接用法整理

1、內聯接&#xff08;典型的聯接運算&#xff0c;使用像 或 <> 之類的比較運算符&#xff09;。包括相等聯接和自然聯接。 內聯接使用比較運算符根據每個表共有的列的值匹配兩個表中的行。例如&#xff0c;檢索 students和courses表中學生標識號相同的所有行。 …

簡述 OAuth 2.0 的運作流程

本文將以用戶使用 github 登錄網站留言為例&#xff0c;簡述 OAuth 2.0 的運作流程。 假如我有一個網站&#xff0c;你是我網站上的訪客&#xff0c;看了文章想留言表示「朕已閱」&#xff0c;留言時發現有這個網站的帳號才能夠留言&#xff0c;此時給了你兩個選擇&#xff1a;…