linux線程操作

初始化條件變量

int pthread_cond_init(pthread_cond_t *cv,pthread_cond_attr *cattr);
函數返回值:返回0表示成功,返回其他表示失敗。
參數:        pthread_cond_attr是用來設置pthread_cond_t的屬性,當傳入的值是NULL的時候表示使用默認的屬性。

函數返回時,創建的條件變量保存在cv所指向的內存中,可以用宏PTHREAD_COND_INITIALIZER來初始化條件變量。值得注意的是不能使用多個線程初始化同一個條件變量,當一個線程要使用條件變量的時候確保它是未被使用的。

?

條件變量的銷毀

int pthread_cond_destroy(pthread_cond_t *cv);
返回值:返回0表示成功,返回其他值表示失敗。

?

條件變量的使用:

int pthread_cond_wait(pthread_cond_t *cv,pthread_mutex_t *mutex)
int pthread_cond_signal(pthread_cond_t *cv);

?

使用方式如下:

pthread_mutex_lock(&mutex)
while or if(線程執行的條件是否成立)pthread_cond_wait(&cond,&mutex);
線程執行
pthread_mutex_unlock(&mutex);

?

?

為什么要加鎖

  1. 線程在執行的部分訪問的是進程的資源,有可能多個線程需要訪問它,為了避免由于線程并發執行所引起的資源競爭,所以要讓每個線程互斥的訪問公共資源。
  2. 如果while或if判斷不滿足線程的執行條件時,線程回調用pthread_cond_wait阻塞自己。pthread_cond_wait被調用線程阻塞的時候,pthread_cond_wait會自動釋放互斥鎖。線程從調用pthread_cond_wait到操作系統把他放在線程等待隊列之后的時候釋放互斥鎖。

?

使用while和if判斷線程執行條件釋放成立的區別。

在多線程資源競爭的時候,在一個使用資源的線程里面(消費者)判斷資源是否可用,不可用便調用pthread_cond_wait,在另一個線程里面(生產者)如果判斷資源可用的話,則會調用pthead_cond_signal發送一個資源可用的信號。

但是在wait成功之后,資源就不一定可以被使用,因為同時有兩個或兩個以上的線程正在等待次資源,wait返回后,資源可能已經被使用了,在這種情況下

while(resource == FALSE)pthread_cond_wait(&cond,&mutex);

如果之后只有一個消費者,就可使用if。

分解pthread_cond_wait動作為以下步驟:

  1. 線程放在等待隊列上,解鎖
  2. 等待pthread_cond_signal或者pthread_cond_broadcast信號之后去競爭鎖
  3. 若競爭到互斥鎖則加鎖

?

有可能多個線程在等待這個資源可用的信號,信號發出去之后只有一個資源可用,但是有A,B兩個線程在等待,B速度比較快,獲得互斥鎖,然后加鎖,消耗資源,然后解鎖,之后A獲得互斥鎖,但它回去發現資源已經被使用了,它便有兩個選擇,一個失去訪問不存在的資源,另一個就是繼續等待,那么等待下去的條件就是使用while,要不然使用if的話pthread_cond_wait返回后,就會順序執行下去。

?

等待線程:

pthread_cond_wait????? 前要加鎖

pthread_cond_wait????? 內部會解鎖,然后等待條件變量被其他線程激活

pthread_cond_wait????? 被激活后會再自動加鎖

?

激活線程

加鎖(和等待線程用同一個鎖)

pthread_cond_signal?? 發送信號(階躍信號前最后判斷有無等待線程)

解鎖

激活線程的上面三個操作再運行時間上都是再等待線程的pthread_cond_wait函數內部。

/***
pthread_if.c
***/
#include<stdio.h>
#include<sys/types.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;int count = 0;void *decrement(void *arg)
{printf("in derment\n");pthread_mutex_lock(&mutex);if(count == 0)pthread_cond_wait(&cond,&mutex);count--;printf("----decrement:%d\n",count);printf("out decrement\n");pthread_mutex_unlock(&mutex);return NULL;
}void *increment(void *arg)
{printf("in increment\n");pthread_mutex_lock(&mutex);count++;printf("-----increment:%d\n",count);if(count != 0){pthread_cond_signal(&cond);}printf("out increment\n");pthread_mutex_unlock(&mutex);return NULL;
}int main()
{pthread_t tid_in,tid_de;pthread_create(&tid_de,NULL,(void*)decrement,NULL);sleep(1);pthread_create(&tid_in,NULL,(void*)increment,NULL);sleep(1);pthread_join(tid_de,NULL);pthread_join(tid_in,NULL);pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);return 0;
}

?

?

/***
pthread_while.c
***/
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>typedef struct node_s
{int data;struct node_s *next;
}node_t;node_t *head = NULL;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;void cleanup_handler(void *arg)
{printf("cleanup_handler is running.\n");free(arg);pthread_mutex_unlock(&mutex);
}void *thread_func(void *arg)
{node_t *p = NULL;pthread_cleanup_push(cleanup_handler,p);while(1){pthread_mutex_lock(&mutex);while(NULL == head)pthread_cond_wait(&cond,&mutex);p = head;head = head->next;printf("process %d node\n",p->data);free(p);pthread_mutex_unlock(&mutex);}pthread_cleanup_pop(0);return NULL;
}int main()
{pthread_t tid;node_t *temp = NULL;int i;pthread_create(&tid,NULL,(void*)thread_func,NULL);for(i = 0; i < 10; i++){temp = (node_t*)malloc(sizeof(node_t));temp->data = i;pthread_mutex_lock(&mutex);temp->next = head;head = temp;pthread_cond_signal(&cond);pthread_mutex_unlock(&mutex);sleep(1);}pthread_cancel(tid);pthread_join(tid,NULL);return 0;}

?

轉載于:https://www.cnblogs.com/wanghao-boke/p/11613064.html

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

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

相關文章

Linux下多線程模擬停車場停車

#include<stdio.h> #include<string.h> #include<unistd.h> #include<stdlib.h> #include<pthread.h>#define ONE_SECOND 1000000 #define RANGE 10 #define PERIOD 2 #define NUM_THREADS 4typedef struct {int *carpark; //用一個數組來模…

【C++學習之路】第一章——C++核心方法總論

1 C核心方法總論 1.1 核心思想 通過實際項目來學習編程&#xff0c;更高效掌握編程規則&#xff0c;以及明白各種語法規則的實際應用。 實驗思想&#xff1a;任何C的參考資料都不可能覆蓋你遇到的所有問題&#xff0c;這個時候&#xff0c;最好的辦法就是&#xff0c;編輯代…

【Verilog HDL學習之路】第一章 Verilog HDL 數字設計總論

1 Verilog HDL 數字設計總論 1.1 幾個重要的概念 EDA&#xff08;Electronic Design Automation&#xff09; 電子技術自動化 EDA工具 類似于軟件工程中的IDE&#xff08;集成開發環境&#xff09;&#xff0c;能夠使用Verilog HDL語言描述電路設計&#xff0c;并且能夠通過邏…

【學會如何學習系列】從嬰兒到大學——學習的本質從未改變過

從嬰兒到大學——學習的本質從未改變過 從我們出生一直到現在&#xff0c;其實&#xff0c;學習的本質從來都沒有改變過&#xff0c;并且&#xff0c;嬰兒時期的我們&#xff0c;是學習能力最強的時候&#xff0c;隨著我們不斷長大&#xff0c;外界的誘惑越來越多&#xff0c;…

【匯編語言學習之路】第一章 匯編語言核心方法論

版權聲明&#xff1a;本學習筆記是本人根據小甲魚“匯編語言學習課程”和《匯編語言》&#xff08;王爽&#xff09;的書籍&#xff0c;來記錄筆記的 1 匯編語言核心方法論 1.1 學習匯編語言的必要性 匯編語言與機器語言是一一對應關系&#xff0c;它的本質是機器語言的代號。…

藍橋單片機賽題及模擬題代碼

鏈接&#xff1a;https://pan.baidu.com/s/1BVB6VILEed0ufqRDMhvALg 提取碼&#xff1a;ukx7

【Verilog HDL學習之路】第二章 Verilog HDL的設計方法學——層次建模

2 Verilog HDL的設計方法學——層次建模 重要的思想&#xff1a; 在語文教學中&#xff0c;應該先掌握核心方法論&#xff0c;再用正確的方法論去做題目&#xff0c;這樣能夠逐漸加深對于方法論的理解&#xff0c;做題的速度和準確率也會越來越高。在Verilog HDL中&#xff0c…

stm32機械臂資料含視頻

這是在網上買的機械臂的資料 含視頻及相關軟件 在這里分享給大家 不過很大 但是內容很全 鏈接&#xff1a;https://pan.baidu.com/s/1Fd18ww8jxLH8ChqomstZtw 提取碼&#xff1a;147g

【Verilog HDL】第四章 模塊的端口連接規則——污水處理模型

先放上連接規則的簡圖&#xff0c;再詳細解釋 1. 構建模型——污水處理之流水模型 我們先將上述結構構件一個簡單模型&#xff0c;以幫助我們理解。 污水&#xff1a;輸入數據凈水&#xff1a;輸出數據雙向數據暫不討論&#xff0c;取輸入和輸出的交集即可污水處理廠&…

藍橋杯嵌入式第七屆模擬題 代碼

鏈接&#xff1a;https://pan.baidu.com/s/1fdGC20A51axxPGpoyRL8-w 提取碼&#xff1a;by4u

三級嵌入式選擇知識點整理

SoC芯片 通用SoC是系統級芯片 既可以是單核 也可以是多核 該芯片中可以包含數字電路 模擬電路 數字模擬混合電路 及射頻電路 片上系統可使用單個芯片進行數據的采集 轉換 儲存 處理 及I/O口功能 智能手機 和平板都使用的SOC WAV是未壓縮的數字音頻 音質與CD相當 音頻視頻壓縮…

【Verilog HDL】命名的規則研究

Verilog命名規范參考資料 1. 什么可以被命名&#xff1f; 模塊的名稱模塊實例的名稱各種數據類型的名稱 這些名稱我們稱之為標識符&#xff0c;標識符的命名規則不再強調&#xff0c;與C語言類似&#xff0c;字母、數字、下劃線&#xff08;_&#xff09;和美元符號&#xf…

【Verilog HDL】深入理解部分語法規則的本質

1. 門級描述 統一規則&#xff1a; 門類型 (輸出&#xff0c;輸入); 細化規則&#xff1a; 與/或門&#xff1a; 多入一出 門 (輸出&#xff0c;輸入1&#xff0c;輸入2,……);緩沖門/非門&#xff1a;一入多出 門 (輸出1&#xff0c;輸出2,……輸出n&#xff0c;輸入); 門…

三級嵌入式填空整理

實時 可預測性是實時系統的重要性能標準 按照響應時間 實時操作系統可分為 1.普通實時操作系統 響應時間一般是秒級 2.強實時操作系統 響應時間為毫秒和微秒級 3.弱實時操作系統 響應時間為數十秒 RTOS 響應中斷請求并完成相應中斷服務子程序的時間非常快 這個時間具有一致性…

【Verilog HDL】從邏輯電路圖到門級建模——人工翻譯的方法論

從左到右&#xff0c;從上到下 先搞定緩沖/非門&#xff0c;再寫與/或門 1. 實例解讀 先以四選一數據選擇器進行說明 對于數字邏輯的部分不再說明&#xff0c;直接進行邏輯電路圖到Verilog門級建模的人工翻譯過程的描述。 1.1 端口和線網分析 確定輸入/輸出端口 輸入端口 …

三級嵌入式 匯編指令匯總

ARM條件碼 EQ 相等 NE 不相等 CS/HS 無符號大于等于 CC/LO 無符號小于 HI 無符號大于 LS 無符號小于等于 GE 帶符號大于等于 L…

【Verilog HDL】語句的并發執行

1. 實踐得到的啟發 先從一個簡單的現象得出結論&#xff0c;Verilog語句是并發執行的&#xff01; 同時&#xff0c;這也是**$monitor系統任務為全局有效**的一個重要支持因素&#xff0c;如果沒有并發&#xff0c;它是完不成這項功能的實現的。 眾所周知&#xff0c;高級語…

linux下 最常用基本命令

常用命令 基本命令 pwd 打印絕對路徑 ls 路徑 列舉文件名 ls 列舉文件的權限 屬于哪個用戶 容量大小 修改…

【數字邏輯】第四章 組合邏輯電路:端口設計 端口拓展的方法

1. 端口設計的方法 1.1 數據選擇器 以四選一數據選擇器為例&#xff0c;需要的不同接口類型為 輸入端口 數據輸入端口地址輸入端口使能端&#xff08;控制與拓展&#xff09; 輸出端口 數據輸出端口 2. 端口拓展的方法——層次建模思想 2.0 兩個拓展方向 2.0.1 “數組型…

GCC及Makefile基本使用教程

GCC .c c原始程序 .C/.cc/.cxx c原始程序 .m objective-C原始程序 .i 已經預處理過的c原始程序 .ii 已經預處理過的c原始程序 .s/.S 匯編原始程序 .h 預處理頭文件 .o 目標文件 .a/.so 編譯后的庫文件 -E 生成預處理文件 -S 生成編譯過的匯編文件 -c 目標文件 .o -o…