作業系統之生產者消費者模型
程式碼如下:
參考:https://saucer-man.com/backend_development/19.html
1 #include <stdio.h>
2 #include <pthread.h>
3 #include<semaphore.h>
4
5 sem_t empty,full; //定義全域性同步訊號量empty,full
6 pthread_mutex_t mutex; //定義一個全域性互斥量,在不同函式中
7 int buffer_count=0; // 定義一個全域性變數,表示管道內得產品數目
8
9 void *producer( void *arg ); //生產者執行緒
10 void *consumer( void *arg ); //消費者執行緒
11
12 int main(int argc , char *argv[]){
13 pthread_t thrd_prod , thrd_cons;
14
15 pthread_mutex_init( &mutex , NULL ); //初始化互斥量
16 sem_init (&empty, 0 , 5); //初始化empty訊號量
17 sem_init (&full, 0, 0); //初始化full訊號量
18 //建立生產者和消費者執行緒
19 if( pthread_create( &thrd_prod , NULL, producer ,
20 NULL ) != 0 )
21 printf( "thread create failed." );
22
23 if( pthread_create( &thrd_cons , NULL, consumer ,
24 NULL ) != 0 )
25 printf( "thread create failed." );
26
27 //等待執行緒結束
28 if( pthread_join( thrd_prod , NULL ) != 0 )
29 printf( " wait thread failed.");
30 if( pthread_join( thrd_cons , NULL ) != 0 )
31 printf( " wait thread failed.");
32 sem_destroy (&full); //釋放同步量
33 sem_destroy(&empty); //釋放同步量
34 pthread_mutex_destroy( &mutex ); //關閉互斥量
35 return 0;
36 }
37
38 void *producer( void *arg){
39 while(1){
40 sem_wait(&empty); //empty-1
41 pthread_mutex_lock( &mutex ); //加鎖
42 //成功佔有互斥量,接下來可以對緩衝區(倉庫)進行生產
43 //操作
44 printf( " producer put a product to buffer.");
45 buffer_count++;
46 printf("the buffer_count is %d\n",buffer_count) ;
47 pthread_mutex_unlock( &mutex ); //解鎖
48 sem_post(&full); //full+1
49 }
50 }
51 void *consumer( void *arg ){
52 while(1)
53 {
54 sem_wait(&full); //full-1
55 pthread_mutex_lock( &mutex ); //加鎖
56 //成功佔有互斥量,接下來可以對緩衝區(倉庫)進行取出
57 //操作
58 printf( " consumer get a product from buffer.");
59 buffer_count--;
60 printf("the buffer_count is %d\n",buffer_count) ;
61 pthread_mutex_unlock( &mutex ); //解鎖
62 sem_post(&empty); //empty-1
63 }
64 }
建立執行緒函式
pthread_create( &thrd_prod , NULL, producer , NULL );
執行緒建立成功時,返回0;否則返回錯誤編號。
第一個引數為指向執行緒識別符號的指標。
第二個引數用來設定執行緒屬性。
第三個引數是執行緒執行函式的起始地址。
最後一個引數是執行函式的引數。
執行緒等待函式
pthread_join( thrd_prod , NULL );
用於等待執行緒thrd_prod結束。
等待執行緒結束函式
pthread_mutex_init( &mutex , NULL );
以動態方式建立互斥鎖,第二個引數指定了新建互斥鎖的屬性。
如果第二個引數為NULL,則使用預設的互斥鎖屬性,預設屬性為快速互斥鎖。
返回0表示成功。
訊號量初始化函式
sem_init (&empty, 0, 5); //初始化empty訊號量
訊號量的資料型別為結構sem_t,它本質上是一個長整型的數。函式sem_init()用來初始化一個訊號量。它的原型為:
extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));
sem為指向訊號量結構的一個指標;pshared不為0時此訊號量在程序間共享,否則只能為當前程序的所有執行緒共享;value給出了訊號量的初始值。
訊號量等待函式
sem_wait(&empty); //empty-1
函式sem_wait( sem_t *sem )被用來阻塞當前執行緒直到訊號量sem的值大於0,解除阻塞後將sem的值減一,表明公共資源經使用後減少。
函式sem_trywait ( sem_t *sem )是函式sem_wait()的非阻塞版本,它直接將訊號量sem的值減一。
sem_post(&full); //full+1
函式sem_post( sem_t *sem )用來增加訊號量的值。當有執行緒阻塞在這個訊號量上時,呼叫這個函式會使其中的一個執行緒不在阻塞,選擇機制同樣是由執行緒的排程策略決定的。
參考
linux下C語言實現生產者消費者問題
https://saucer-man.com/backend_development/19.html
pthread_create函式的詳細講解(包括向執行緒函式傳遞引數詳解)
https://blog.csdn.net/liangxanhai/article/details/7767430
pthread_join用法解釋
https://blog.csdn.net/danelumax2/article/details/24191411
互斥鎖 pthread_mutex_init()函式
https://blog.csdn.net/yasi_xi/article/details/19112077
sem_init,sem_post,sem_wait 訊號量的用法解釋