欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

超輕量 pthread 集結(jié)點(diǎn)實(shí)現(xiàn)

系統(tǒng) 2347 0

我需要的 pthread 線程集結(jié)點(diǎn)功能,使用同一集結(jié)點(diǎn)的線程將通過(guò) rend_wait 函數(shù)等待,當(dāng)集結(jié)點(diǎn)到達(dá)指定數(shù)量的線程后同時(shí)激發(fā)繼續(xù)執(zhí)行。使用 pthread 的 mutex 和 cond 超輕量實(shí)現(xiàn)。下面 rend.h 是集結(jié)點(diǎn)實(shí)現(xiàn),rendezvous.c 是測(cè)試應(yīng)用。

C代碼
  1. /*
  2. *rend.h
  3. *
  4. *Createdon:2009-11-14
  5. *Author:liuzy(lzy.dev@gmail.com)
  6. */
  7. #ifndefREND_H_
  8. #defineREND_H_
  9. #include<pthread.h>
  10. #include<assert.h>
  11. struct rend_t{
  12. volatile int count;
  13. pthread_mutex_tcount_lock;
  14. pthread_cond_tready;
  15. };
  16. #defineDECLARE_REND(name,count)/
  17. struct rend_tname={(count),PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER}
  18. int rend_init( struct rend_t*prend, int count){
  19. int ret=0;
  20. assert(prend);
  21. prend->count=count;
  22. if ((ret=pthread_mutex_init(&prend->count_lock,NULL)))
  23. return ret;
  24. if ((ret=pthread_cond_init(&prend->ready,NULL)))
  25. return ret;
  26. return EXIT_SUCCESS;
  27. }
  28. int rend_wait( struct rend_t*prend){
  29. int ret=0;
  30. assert(prend);
  31. if ((ret=pthread_mutex_lock(&prend->count_lock)))
  32. return ret;
  33. /*checkcountvalueisreadytoweakupblockcode*/
  34. if (prend->count==1){
  35. if ((ret=pthread_cond_broadcast(&prend->ready)))
  36. return ret;
  37. if ((ret=pthread_mutex_unlock(&prend->count_lock)))
  38. return ret;
  39. } else {
  40. prend->count--;
  41. ret=pthread_cond_wait(&prend->ready,&prend->count_lock);
  42. prend->count++;
  43. if (ret){
  44. pthread_mutex_unlock(&prend->count_lock);
  45. return ret;
  46. }
  47. if ((ret=pthread_mutex_unlock(&prend->count_lock)))
  48. return ret;
  49. }
  50. return EXIT_SUCCESS;
  51. }
  52. int rend_free( struct rend_t*prend){
  53. int ret=0;
  54. assert(prend);
  55. prend->count=0;
  56. if ((ret=pthread_mutex_destroy(&prend->count_lock)))
  57. return ret;
  58. if ((ret=pthread_cond_destroy(&prend->ready)))
  59. return ret;
  60. return EXIT_SUCCESS;
  61. }
  62. #endif/*REND_H_*/

rend 使用更簡(jiǎn)單:

  1. 定義/初始化 rend_t 集結(jié)點(diǎn)對(duì)象。DECLARE_REND 宏用于靜態(tài)定義,rend_init 函數(shù)可以對(duì)動(dòng)態(tài)創(chuàng)建的集結(jié)點(diǎn)結(jié)構(gòu)初始化;
  2. pthread 線程通過(guò)調(diào)用 rend_wait 函數(shù) P/V 集結(jié)狀態(tài)。集結(jié)關(guān)系的線程要 P/V 在同一個(gè) rend_t 集結(jié)對(duì)象上;
  3. 釋放集結(jié)對(duì)象,rend_free 函數(shù)。

以上函數(shù)都是成功返回 0,出錯(cuò)返回 errno 值(非 0)。

C代碼
  1. /*
  2. ==============================
  3. Name:rendezvous.c
  4. Author:liuzy(lzy.dev@gmail.com)
  5. Version:0.1
  6. ==============================
  7. */
  8. #include<stdio.h>
  9. #include<stdlib.h>
  10. #include<stdarg.h>/*va_list*/
  11. #include<unistd.h>
  12. #include<string.h>
  13. #include<errno.h>/*errno*/
  14. #include<syslog.h>/*forsyslog(2)andlevel*/
  15. #include<pthread.h>
  16. #include"rend.h"
  17. static int daemon_proc=0; /*forsysloginerr_doit*/
  18. #defineMAXLINE4096/*maxtextlinelength*/
  19. void err_doit( int errnoflag, int level, const char *fmt, va_list ap){
  20. char buf[MAXLINE+1]={0};
  21. int errno_save=errno,n=0;
  22. #ifdefHAVE_VSNPRINTF
  23. vsnprintf(buf,MAXLINE,fmt,ap);
  24. #else
  25. vsprintf(buf,fmt,ap);
  26. #endif/*HAVE_VSNPRINTF*/
  27. n=strlen(buf);
  28. if (errnoflag)
  29. snprintf(buf+n,MAXLINE-n, ":%s" ,strerror(errno_save));
  30. strcat(buf, "/n" );
  31. if (daemon_proc){
  32. syslog(level, "%s" ,buf);
  33. } else {
  34. fflush(stdout);
  35. fputs(buf,stderr);
  36. fflush(stderr);
  37. }
  38. return ;
  39. }
  40. void err_msg( const char *fmt,...){
  41. va_list ap;
  42. va_start(ap,fmt);
  43. err_doit(0,LOG_INFO,fmt,ap);
  44. va_end(ap);
  45. return ;
  46. }
  47. void err_sys( const char *fmt,...){
  48. va_list ap;
  49. va_start(ap,fmt);
  50. err_doit(1,LOG_ERR,fmt,ap);
  51. va_end(ap);
  52. exit(EXIT_FAILURE);
  53. }
  54. #defineTHREAD_COUNT100/*rendezvoustestthreadworkers*/
  55. struct worker_arg{
  56. int worker_id;
  57. struct rend_t*prend;
  58. };
  59. static void *pthread_worker( void *arg){
  60. struct worker_arg*parg=( struct worker_arg*)arg;
  61. err_msg( "worker#%drunning." ,( int )parg->worker_id);
  62. srand(parg->worker_id*2);
  63. sleep(rand()%5);
  64. rend_wait(parg->prend); /*workersrendezvous*/
  65. err_msg( "worker#%dexiting." ,( int )parg->worker_id);
  66. return EXIT_SUCCESS;
  67. }
  68. int main( void ){
  69. int idx=0;
  70. void *exitcode=NULL;
  71. pthread_tthds[THREAD_COUNT];
  72. struct worker_argarg[THREAD_COUNT];
  73. DECLARE_REND(rend,THREAD_COUNT);
  74. err_msg( "workerscreating." );
  75. for (idx=0;idx<THREAD_COUNT;idx++){
  76. arg[idx].prend=&rend;
  77. arg[idx].worker_id=idx;
  78. if (pthread_create(thds+idx,NULL,pthread_worker,( void *)&arg[idx]))
  79. err_sys( "worker#%dcreateerror." ,idx);
  80. }
  81. puts( "workersexiting." );
  82. for (idx=0;idx<THREAD_COUNT;idx++)
  83. if (pthread_join(thds[idx],&exitcode)||(exitcode!=EXIT_SUCCESS))
  84. err_msg( "worker#%dexiterror." ,idx);
  85. err_msg( "alldone.exit0." );
  86. rend_free(&rend);
  87. return EXIT_SUCCESS;
  88. }

看了下 semaphore os syscall 及其 infrastructure,也許以后還需要進(jìn)程間(非 pthread)集結(jié)時(shí)用得上。kernel 實(shí)現(xiàn)的超強(qiáng)啊,呵呵~

// 2009.11.17 14:34 添加 ////

快速用戶空間互斥鎖(Futex)
快速用戶空間互斥鎖(fast userspace mutex,F(xiàn)utex)是快速的用戶空間的鎖,是對(duì)傳統(tǒng)的System V同步方式的一種替代,傳統(tǒng)同步方式如:信號(hào)量、文件鎖和消息隊(duì)列,在每次鎖訪問(wèn)時(shí)需要進(jìn)行系統(tǒng)調(diào)用。而futex僅在有競(jìng)爭(zhēng)的操作時(shí)才用系統(tǒng)調(diào)用訪問(wèn)內(nèi)核,這樣,在競(jìng)爭(zhēng)出現(xiàn)較少的情況下,可以大幅度地減少工作負(fù)載
futex在非競(jìng)爭(zhēng)情況下可從用戶空間獲取和釋放,不需要進(jìn)入內(nèi)核。與信號(hào)量類似,它有一個(gè)可以原子增減的計(jì)數(shù)器,進(jìn)程可以等待計(jì)數(shù)器值變?yōu)檎龜?shù)。用戶進(jìn)程通過(guò)系統(tǒng)調(diào)用對(duì)資源的競(jìng)爭(zhēng)作一個(gè)公斷。
futex 是一個(gè)用戶空間的整數(shù)值,被多個(gè)線程或進(jìn)程共享。Futex的系統(tǒng)調(diào)用對(duì)該整數(shù)值時(shí)進(jìn)行操作,仲裁競(jìng)爭(zhēng)的訪問(wèn)。 glibc中的NPTL庫(kù)封裝了futex 系統(tǒng)調(diào)用,對(duì)futex接口進(jìn)行了抽象。用戶通過(guò)NPTL庫(kù)像傳統(tǒng)編程一樣地使用線程同步API函數(shù),而不會(huì)感覺(jué)到futex的存在。
futex 的實(shí)現(xiàn)機(jī)制是:如果當(dāng)前進(jìn)程訪問(wèn)臨界區(qū)時(shí),該臨界區(qū)正被另一個(gè)進(jìn)程使用,當(dāng)前進(jìn)程將鎖用一個(gè)值標(biāo)識(shí),表示“有一個(gè)等待者正掛起”,并且調(diào)用 sys_futex(FUTEX_WAIT)等待其他進(jìn)程釋放它。內(nèi)核在內(nèi)部創(chuàng)建futex隊(duì)列,以便以后與喚醒者匹配等待者。當(dāng)臨界區(qū)擁有者線程釋放了 futex,它通過(guò)變量值發(fā)出通知表示還有多個(gè)等待者在掛起,并調(diào)用系統(tǒng)調(diào)用sys_futex(FUTEX_WAKE)喚醒它們。一旦所有等待者已獲取資源并釋放鎖時(shí),futex回到非競(jìng)爭(zhēng)狀態(tài),并沒(méi)有內(nèi)核狀態(tài)與它相關(guān)。
robust futex是為了解決futex鎖崩潰而對(duì)futex進(jìn)行了增強(qiáng)。例如:當(dāng)一個(gè)進(jìn)程在持有pthread_mutex_t鎖正與其他進(jìn)程發(fā)生競(jìng)爭(zhēng)時(shí),進(jìn)程因某種意外原因而提前退出,如:進(jìn)程發(fā)生段錯(cuò)誤,或者被用戶用shell命令kill -9-ed”強(qiáng)行退出,此時(shí),需要有一種機(jī)制告訴等待者“鎖的最一個(gè)持有者已經(jīng)非正常地退出”?!?
為了解決此類問(wèn)題,NPTL創(chuàng)建了robust mutex用戶空間API pthread_mutex_lock(),如果鎖的擁有者進(jìn)程提前退出,pthread_mutex_lock()返回一個(gè)錯(cuò)誤值,新的擁有者進(jìn)程可以決定是否可以安全恢復(fù)被鎖保護(hù)的數(shù)據(jù)。

有幾點(diǎn)不還不理解:

  1. “futex 如果說(shuō)是一個(gè)用戶空間的整數(shù)值,那怎么被多個(gè)進(jìn)程共享?Futex 系統(tǒng)調(diào)用在 kernel 態(tài)怎么操作該值并仲裁競(jìng)爭(zhēng)?這是那種直接映射到 userspace 的 kernel 地址么。 這個(gè)需要程序間通過(guò) mmap 在共享段中訪問(wèn),與 futex 沒(méi)什么關(guān)系。
  2. 這個(gè)“robust futex”機(jī)制指的應(yīng)該就是 SVRx 傳統(tǒng) sem IPC 里的 SEM_UNDO flag 吧?

一篇不錯(cuò)的文章,引發(fā)對(duì) glibc nptl 實(shí)現(xiàn)源碼的探索:

關(guān)于信號(hào)量與線程互斥鎖的區(qū)別與實(shí)現(xiàn)

超輕量 pthread 集結(jié)點(diǎn)實(shí)現(xiàn)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦?。?!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 国产日韩欧美三级 | 欧美精品免费线视频观看视频 | 波多野结衣的一级片 | 羞羞的小视频 | 欧美激情日韩 | 国产乱码精品一区二区三上 | 台湾三级无遮挡在线播放 | 国产一区精品 | 国产成人禁片免费观看 | 中文字幕一区二区精品区 | 五月天婷婷网站 | 二区三区视频 | 亚洲精品vr一区 | 九九热在线免费观看 | 99re视频在线观看 | 成人欧美视频在线观看 | 91在线亚洲精品专区 | 国内精品一区二区三区 | 奇米影视奇米色777欧美 | 精品国产三级 | 杏美月av | 国产美女久久 | 色婷婷久久免费网站 | 欧美日韩精品一区二区三区蜜桃 | 欧美性色生活片免费播放 | 一本到在线观看视频不卡 | 操你啦免费视频 | 一区二区高清视频 | 两女互慰磨豆腐视频在线观看 | 黄色片在线免费看 | 日日操视频 | 天天操,夜夜操 | 久久伊人免费视频 | 久久亚洲国产精品日日av夜夜 | 一区二区在线不卡 | 成人做爽爽爽爽免费国产软件 | 国产精品一二三区 | 小明www永久在线看 国产美女一区二区三区 | 天天草视频| 日本激情视频一区二区三区 | 人人九九 |