多執行緒程式設計——條件變數
阿新 • • 發佈:2018-12-29
#include <pthread.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> /* 靜態方式初始化一個互斥鎖和一個條件變數 */ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; /* 指向執行緒控制塊的指標 */ static pthread_t tid1; static pthread_t tid2; /* 函式返回值檢查 */ static void check_result(char* str,int result) { if (0 == result) { printf("%s successfully!\n",str); } else { printf("%s failed! error code is %d\n",str,result); } } /* 生產者生產的結構體資料,存放在連結串列裡 */ struct node { int n_number; struct node* n_next; }; struct node* head = NULL; /* 連結串列頭,是共享資源 */ /* 消費者執行緒入口函式 */ static void* consumer(void* parameter) { struct node* p_node = NULL; pthread_mutex_lock(&mutex); /* 對互斥鎖上鎖 */ while (1) { while (head == NULL) /* 判斷連結串列裡是否有元素 */ { pthread_cond_wait(&cond,&mutex); /* 嘗試獲取條件變數 */ } /* pthread_cond_wait()會先對mutex解鎖, 然後阻塞在等待佇列,直到獲取條件變數被喚醒, 被喚醒後,該執行緒會再次對mutex上鎖,成功進入臨界區。 */ p_node = head; /* 拿到資源 */ head = head->n_next; /* 頭指標指向下一個資源 */ /* 列印輸出 */ printf("consume %d\n",p_node->n_number); free(p_node); /* 拿到資源後釋放節點佔用的記憶體 */ } pthread_mutex_unlock(&mutex); /* 釋放互斥鎖 */ return 0; } /* 生產者執行緒入口函式 */ static void* product(void* patameter) { int count = 0; struct node *p_node; while(1) { /* 動態分配一塊結構體記憶體 */ p_node = (struct node*)malloc(sizeof(struct node)); if (p_node != NULL) { p_node->n_number = count++; pthread_mutex_lock(&mutex); /* 需要操作head這個臨界資源,先加鎖 */ p_node->n_next = head; head = p_node; /* 往連結串列頭插入資料 */ pthread_mutex_unlock(&mutex); /* 解鎖 */ printf("produce %d\n",p_node->n_number); pthread_cond_signal(&cond); /* 發訊號喚醒一個執行緒 */ usleep(2); /* 休眠2微秒 */ } else { printf("product malloc node failed!\n"); break; } } } /* 使用者應用入口 */ int application_init() { int result; /* 建立生產者執行緒,屬性為預設值,入口函式是product,入口函式引數為NULL*/ result = pthread_create(&tid1,NULL,product,NULL); check_result("product thread created ",result); /* 建立消費者執行緒,屬性為預設值,入口函式是consumer,入口函式引數是NULL */ result = pthread_create(&tid2,NULL,consumer,NULL); check_result("consumer thread created ",result); return 0; } int main() { int i ; application_init(); i=100; do{ sleep(1); }while(i--); }
執行結果:
-bash-3.2$ ./app
product thread created successfully!
consumer thread created successfully!
produce 0
consume 0
produce 1
consume 1
produce 2
consume 2
produce 3
consume 3
produce 4
consume 4
produce 5
consume 5
produce 6
consume 6
produce 7
consume 7
produce 8
consume 8
produce 9
consume 9
produce 10
consume 10
produce 11
consume 11
produce 12
consume 12
produce 13
consume 13
produce 14
consume 14
produce 15
consume 15
produce 16
consume 16