1. 程式人生 > 實用技巧 >作業系統之生產者消費者模型

作業系統之生產者消費者模型

程式碼如下:

參考: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 訊號量的用法解釋

https://blog.csdn.net/allens_zhou/article/details/40425375