日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

浅析linux下的条件变量

發布時間:2023/11/30 linux 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅析linux下的条件变量 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??一.條件變量

? ? 條件變量是用來等待線程而不是上鎖的,條件變量通常和互斥鎖一起使用。條件變量之所以要和互斥鎖一起使用,主要是因為互斥鎖的一個明顯的特點就是它只有兩種狀態:鎖定和非鎖定,而條件變量可以通過允許線程阻塞和等待另一個線程發送信號來彌補互斥鎖的不足,所以互斥鎖和條件變量通常一起使用

? ? 當條件滿足的時候,線程通常解鎖并等待該條件發生變化,一旦另一個線程修改了環境變量,就會通知相應的環境變量喚醒一個或者多個被這個條件變量阻塞的線程。這些被喚醒的線程將重新上鎖,并測試條件是否滿足。一般來說條件變量被用于線程間的同步;當條件不滿足的時候,允許其中的一個執行流掛起和等待。

條件變量中常用的API:

? ? ?1).條件變量類型為:pthread_cond_t ,類似互斥變量,條件變量的初始化有兩種方式:

? ? ? 靜態:pthread_cond_t mycon=PTHREAD_COND_INITIALIZER;

? ? ? 動態:通過調用pthread_cond_init函數,函數原型為:

[cpp]?view plain?copy
  • 靜態:pthread_cond_t?mycon=PTHREAD_COND_INITIALIZER;??
  • ? ? ?cond:環境變量.

    ? ? ?attr:條件變量屬性.

    ? ? ?成功返回0,失敗返回錯誤碼.

    ? ? ?2).條件變量摧毀函數:pthread_cond_destroy(&mycond);

    [cpp]?view plain?copy
  • int?pthread_cond_destroy(pthread_cond_t?*cond);??
  • ? ? ?成功返回0,失敗返回錯誤碼.

    ? ? ?摧毀所指定的條件變量,同時將會釋放所給它分配的資源。調用該函數的進程也并不等待在參數所指定的條件變量上。

    ? ? ?3).條件變量等待函數。pthread_cond_wait(&mycond,&mylock);

    ? ? ?

    [cpp]?view plain?copy
  • int?pthread_cond_timedwait(pthread_cond_t?*restrict?cond,??
  • ???????????pthread_mutex_t?*restrict?mutex,??
  • ???????????const?struct?timespec?*restrict?abstime);??
  • ????int?pthread_cond_wait(pthread_cond_t?*restrict?cond,??
  • ???????????pthread_mutex_t?*restrict?mutex);??

  • ? ? cond:條件變量

    ? ? mutex:互斥鎖

    ?pthread_cond_wait和pthread_cond_timedwait的區別:

    ? ??pthread_cond_timedwait函數類型與函數pthread_cond_wait,區別在于,如果達到或是超過所引用的參數*abstime,它將結束并返回錯誤ETIME.

    ? ? timespec

    [cpp]?view plain?copy
  • typedef?struct?timespec??
  • ???{??
  • ??????time_t?????tv_sec;????//!>?秒??
  • ??????long?????tv_nsex;????//!>?毫秒??
  • ???}timespec_t;??

  • ? ? 當時間超過之前預設定的時會返回錯誤.

    ? ? 4).條件變量通知函數:pthread_cond_signal和pthread_cond_broadcast

    [cpp]?view plain?copy
  • int?pthread_cond_broadcast(pthread_cond_t?*cond);??
  • int?pthread_cond_signal(pthread_cond_t?*cond);??

  • pthread_cond_signal和pthread_cond_broadcast的區別:

    ? ? ? ?pthread_cond_signal:只喚醒一個在相同條件變量中阻塞的線程將會被喚醒

    ? ? ? ?pthread_cond_broadcast:喚醒等待隊列中的所有線程

    二.一個關于互斥鎖和條件變量的栗子

    ? ?栗子:用互斥鎖和條件變量的概念實現一個簡單的生產者和消費者的模型。

    ?生產者和消費者模型:

    ? ? 1).滿足互斥與同步條件,用互斥鎖和條件變量實現

    ? ? 2).多個生產者和消費者:生產者和生產者屬于互斥關系;生產者和消費者屬于互斥和同步關系;消費者和消費者屬于競爭關系,需要互斥鎖

    ? ? 3).生產者和消費者模型中存在如下幾種關系和角色:3種關系,2種角色,1種交換媒介(一般是一段內存)

    ? ? 下例以單生產者和單消費者,交換媒介為鏈表實現的生產者消費者模型

    ? ? ?

    [cpp]?view plain?copy
  • procon.c??
  • ??
  • #include<stdio.h>??
  • #include<stdlib.h>??
  • #include<assert.h>??
  • #include<pthread.h>??
  • ??
  • typedef?struct?LinkNode??
  • {??
  • ????int?data;??
  • ????struct?LinkNode?*next;??
  • }Node;??
  • ??
  • pthread_mutex_t?mylock=PTHREAD_MUTEX_INITIALIZER;??
  • pthread_cond_t?mycond=PTHREAD_COND_INITIALIZER;??
  • ??
  • Node?*CreatNode(int?data)??
  • {??
  • ????Node?*NewNode=(Node?*)malloc(sizeof(Node));??
  • ????if(NULL?==?NewNode)??
  • ????{??
  • ????????perror("malloc");??
  • ????????return?NULL;??
  • ????}??
  • ????NewNode->data=data;??
  • ????NewNode->next=NULL;??
  • ????return?NewNode;??
  • }??
  • ??
  • void?InitLink(Node?**head)??
  • {??
  • ????*head=CreatNode(0);??
  • }??
  • ??
  • int?IsEmpty(Node?*head)??
  • {??
  • ????assert(head);??
  • ????if(head->next)??
  • ????????return?0;????//not?empty??
  • ????else??
  • ????????return?1;????//empty??
  • }??
  • ??
  • void?PushFront(Node?*head,int?data)??
  • {??
  • ????assert(head);??
  • ????Node?*NewNode=CreatNode(data);??
  • ????NewNode->next=head->next;??
  • ????head->next=NewNode;??
  • }??
  • ??
  • void?PopFront(Node?*head,int?*data)??
  • {??
  • ????assert(data);??
  • ????assert(head);??
  • ????if(IsEmpty(head))??
  • ????{??
  • ????????printf("empty?link\n");??
  • ????????return?;??
  • ????}??
  • ????Node?*del=head->next;??
  • ????*data=del->data;??
  • ????head->next=del->next;??
  • ????free(del);??
  • ????del=NULL;??
  • }??
  • ??
  • void?DisplayLink(Node?*head)??
  • {??
  • ????assert(head);??
  • ????Node?*cur=head->next;??
  • ????while(cur)??
  • ????{??
  • ????????printf("%d?",cur->data);??
  • ????????cur=cur->next;??
  • ????}??
  • ????printf("\n");??
  • }??
  • ??
  • void?DestroyLink(Node?*head)??
  • {??
  • ????int?data=0;??
  • ????assert(head);??
  • ????while(!IsEmpty(head))??
  • ????{??
  • ????????PopFront(head,&data);??
  • ????}??
  • ????free(head);??
  • }??
  • ??
  • void?*product_run(void?*arg)??
  • {??
  • ????int?data=0;??
  • ????Node?*head=(Node?*)arg;??
  • ????while(1)??
  • ????{??
  • ????????usleep(100000);??
  • ????????data=rand()%1000;??
  • ????????pthread_mutex_lock(&mylock);??
  • ????????PushFront(head,data);??
  • ????????pthread_mutex_unlock(&mylock);??
  • ????????pthread_cond_signal(&mycond);??
  • ????????printf("product?is?done,data=%d\n",data);??
  • ????}??
  • }??
  • ??
  • void?*consumer_run(void?*arg)??
  • {??
  • ????int?data=0;??
  • ????Node?*head=(Node?*)arg;??
  • ????while(1)??
  • ????{??
  • ????????pthread_mutex_lock(&mylock);??
  • ????????while(IsEmpty(head))??
  • ????????{??
  • ????????????pthread_cond_wait(&mycond,&mylock);??
  • ????????}??
  • ????????PopFront(head,&data);??
  • ????????pthread_mutex_unlock(&mylock);??
  • ????????printf("consumer?is?done,data=%d\n",data);??
  • ????}??
  • }??
  • ??
  • void?testprocon()??
  • {??
  • ????Node?*head=NULL;??
  • ????InitLink(&head);??
  • ????pthread_t?tid1;??
  • ????pthread_t?tid2;??
  • ????pthread_create(&tid1,NULL,product_run,(void?*)head);??
  • ????pthread_create(&tid2,NULL,consumer_run,(void?*)head);??
  • ??
  • ????pthread_join(tid1,NULL);??
  • ????pthread_join(tid2,NULL);??
  • ????DestroyLink(head);??
  • ????pthread_mutex_destroy(&mylock);??
  • ????pthread_cond_destroy(&mycond);??
  • ??
  • }??
  • int?main()??
  • {??
  • ????testprocon();??
  • ????return?0;??
  • }??
  • ??
  • Makefile??
  • procon:procon.c??
  • ????gcc?-o?$@?$^?-lpthread??
  • .PHONY:clean??
  • clean:??
  • ????rm?-f?procon??


  • ? ??

    總結:

    ? ?條件變量用在某個線程需要在某種條件才去保護它將要操作的臨界區的情況下,從而避免了線程不斷輪詢檢查該條件是否成立而降低效率的情況,這是實現了效率提高。

    ? 希望對讀者有幫助吧~~~~

    ? ??

    總結

    以上是生活随笔為你收集整理的浅析linux下的条件变量的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。