C语言使用信号量(Linux)
在windows中使用信號量已經在另一篇文章中講過了,信號量的詳細細節也已經展示了,本文介紹如何在linux環境下使用c語言編寫信號量類型的例子代碼。
windows c語言使用信號量
與windows環境下不同,在linux下,頭文件unistd.h或者pthread.h都沒有直接包含P,V操作,也就是wait(),signal(),也即信號量的P,V操作需要自行編程實現。信號量結構體(參考上面鏈接)已經清楚,但是這還不夠,實現信號量需要滿足以下兩個條件:
1.信號量操作只能是原子操作
2.除了P,V操作外,其他函數無法操作信號量
我們先看Linux下C語言提供的相關函數:
1.pthread_t; 2.pthread_mutex_t; 3.pthread_cond_t; 4.pthread_mutex_lock(); 5.pthread_mutex_unlock(); 6.pthread_cond_wait(); 7.pthread_cond_signal(); 8.pthread_mutex_init(); 9.pthread_cond_init();1-3為相關變量定義,4、5為互斥訪問的鎖操作,6、7為條件變量,8、9為初始化函數。
函數具體用法可以使用命令查看:
鎖操作可以實現互斥訪問,條件變量可以實現進程同步功能,因此這些函數可以組成信號量操作,函數具體內容就不再贅述。
首先定義信號量結構體:
value表示資源量,mutex實現原子操作,cond實現阻塞等待以及喚醒。
P操作即首先占用一個資源量,如果不夠則阻塞,資源夠用立即返回:
V操作首先釋放一個資源量,并調喚醒一個條件變量,這里不用判斷有沒有被阻塞的進程,條件變量cond已經幫你實現了:
void sema_signal(sema_t *sema) {pthread_mutex_lock(&sema->mutex);sema->value++;pthread_cond_signal(&sema->cond);pthread_mutex_unlock(&sema->mutex); }這樣就完整實現了P,V操作。
下面看一個使用信號量的例子:
- 系統中有3個線程:生產者、計算者、消費者
- 系統中有2個容量為4的緩沖區:buffer1、buffer2
- 生產者
- 生產’a’、‘b’、‘c’、‘d’、‘e’、‘f’、‘g’、'h’八個字符
- 放入到buffer1
- 打印生產的字符
- 計算者
- 從buffer1取出字符
- 將小寫字符轉換為大寫字符,按照 input:OUTPUT 的格式打印
- 放入到buffer2
- 消費者
- 從buffer2取出字符
- 打印取出的字符
- 程序輸出結果(實際輸出結果是交織的)
很明顯,需要五個信號量:
sema_t mutex1,mutex2;//互斥訪問緩沖區 sema_t wait_empty_buff1; sema_t wait_full_buff1; sema_t wait_empty_buff2; sema_t wait_full_buff2;produce線程負責向buffer1中寫數據,有幾個要求:
1.buff1互斥訪問
2.緩沖區滿不能寫
3.寫完通知緩沖區滿
consume線程與produce類似,也有如上述三個要求,但是是2、3是相反的并且互斥訪問buff2:
1.buff2互斥訪問
2.緩沖區空不能拿
3.拿完通知緩沖區空
compute比較復雜,是上述兩個線程的結合體,代碼如下:
void *compute() {int item,item_res;for(int i=0;i<item_count;i++){sema_wait (&wait_full_buff1);sema_wait (&mutex1);item=get_item(1);sema_signal (&mutex1);sema_signal (&wait_empty_buff1);item_res=item-('a'-'A');printf("Compute item: %c-->%c\n",item,item_res);sema_wait (&wait_empty_buff2);sema_wait (&mutex2);put_item(2,item_res);sema_signal (&mutex2);sema_signal (&wait_full_buff2);}return NULL; }由buff1拿出計算后放入buff2,拿的時候buff1不能空,放的時候buff2不能滿。
信號量初始化:
至此全部完畢。
題目2:
系統中有2個線程:ping 線程和 pong 線程
- ping 線程先執行
- ping 線程執行流程如下
- 打印輸出 ping
- 等待 pong 線程輸出
- 執行第 1 步
- pong 線程執行流程如下
- 打印輸出 pong
- 等待 ping 線程輸出
- 執行第 1 步
- 程序輸出結果
ping
pong
ping
pong
…
想法類似,讀者可以自行實現
全部完整代碼地址
總結
以上是生活随笔為你收集整理的C语言使用信号量(Linux)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: KITTY数据集 下载 及 使用
- 下一篇: Linux C 信号量