1. 程式人生 > >19.執行緒同步:訊號量—>[單生產者/單消費者]單鏈表的插入和刪除

19.執行緒同步:訊號量—>[單生產者/單消費者]單鏈表的插入和刪除

1.訊號量

1.訊號量本質
	訊號量是鎖,是一種升級的mutex
	訊號量在初始化時,可以指定共享資源的數量
	

2.相關函式

#include<semaphore.h>  //標頭檔案

sem_t sem; //訊號量型別

int sem_destroy(sem_t *sem); //銷燬
int sem_init(sem_t *sem, int pshared, unsigned int value); //初始化訊號量
	int pshared
		0-執行緒同步
		1-程序同步
	value:最多有幾個執行緒可以操作共享資料(共享資源的最大值)
	
P操作:
	int sem_wait(sem_t *sem);
	int sem_trywait(sem_t *sem);  //不阻塞,直接返回錯誤碼
	int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); //[限時]
V操作:
	int sem_post(sem_t *sem);

案例:[單生產者/單消費者]單鏈表的插入和刪除

  sem_t produce;                                                                                                                 
  sem_t custom;                                                                                                                  
                                                                                                                                 
  typedef struct node{                                                                                                           
    int data;                                                                                                                    
    struct node* next;                                                                                                           
  }LNode;                                                                                                                                                                                                                                        
  LNode* head=NULL;                                                                                                              
                                                                                                                                 
  void* producer(void* arg){                                                                                                     
    while(1){                                                                                                                    
      LNode* newnode=(LNode*)malloc(sizeof(LNode));                                                                              
      newnode->data=rand()%100;                                                                                                  
      newnode->next=NULL;                                                                                                        
                                                                                                                                 
      sem_wait(&produce);  // 生產者獲得還能生產幾個產品,P(produce)
                                                                                                                                 
      newnode->next=head;  head=newnode; //insert node                                                                           
      printf("produce=%d\n",newnode->data);                                                                                      
                                                                                                                                 
      sem_post(&custom); //生產者生產完產品後,V(custom)
                                                                                                                                 
      sleep(rand()%3);                                                                                                           
    }                                                                                                                            
    return NULL;                                                                                                                 
  }  
  void* customer(void* arg){                                                                                                     
    while(1){                                                                                                                    
      sem_wait(&custom);  //消費者獲得產品,P(custom)
                                                                                                                                 
      LNode* delnode=head; head=head->next;                                                                                      
      printf("      custom=%d\n",delnode->data);                                                                                 
      free(delnode);                                                                                                             
                                                                                                                                 
      sem_post(&produce); //                                                          
                                                                                                                                 
      sleep(rand()%3);                                                                                                           
    }                                                                                                                            
    return NULL;                                                                                                                 
  }                                                                                                                              
  int main(){                                                                                                                    
    sem_init(&produce,0,10);  //初始時:最多允許生產10個產品                                                                                                    
    sem_init(&custom,0,0); //初始時:不允許消費產品                                                                                 
                                                                                                                                 
    pthread_t tid1,tid2;                                                                                                         
    pthread_create(&tid1,NULL,producer,NULL);                                                                                    
    pthread_create(&tid2,NULL,customer,NULL);                                                                                    
                                                                                                                                 
    pthread_join(tid1,NULL);                                                                                                     
    pthread_join(tid2,NULL);                                                                                                     

    sem_destroy(&produce);
    sem_destroy(&custom);
  
    return 0;
  }