Ideas
Producers and consumers (mutual exclusion and synchronization). The resource is simulated with a queue (to be locked, only one thread can operate the queue at a time).
M a producer. Get the lock, and product dissatisfaction, can be produced. When the product is full, wait for the consumer to wake up. When the product from empty to not empty, inform the consumer.
n a consumer. Get the lock, and have the product, in order to consume. When the product is empty, wait for the producer to wake up. When the product is filled to discontent, inform the producer.
Producer Conditions: Queue dissatisfaction
Consumer conditions: queue is not empty
So there are two conditional variables.
Code
/************************************************************************* > File name:main.c > Author: Krischou > Mail:[email protected] > Created time:tue-02:55:01 PM CST ******************************** ****************************************/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<pthread.h>#include<unistd.h>#defineCNT 20/* produces up to 20 products *//*simulate a workshop with a queue*//*both front and tail initialization are 0,tail the next array-space subscript that is generated by the next resource*/typedefstructtag{intS_ARR[CNT +1] ;/*production of 20 products, there must be 21 space, because if the space is full of products, can not distinguish between the queue full and the queue empty*/ intS_front; intS_tail;} QUEUE,*Pqueue; QUEUE My_que;/*resource is empty*/intQue_empty (Pqueue PQ) {returnPQ->s_front = = PQS_tail;}/*resource is full*/intQue_full (Pqueue PQ) {return(PQ-S_tail +1)% (cnt+1) = = PQS_front;}intque_cnt (Pqueue PQ) {return(PQ, S_TAIL-PQ->s_front + CNT +1)% (CNT +1) ;} pthread_mutex_t Mutex;p thread_cond_t Cond_pro, Cond_con;void* Pro_handler (void*Arg) {Pthread_detach (pthread_self ()); while(1) {Pthread_mutex_lock (&mutex); while(Que_full (&My_que)) {pthread_cond_wait (&cond_pro, &mutex); } My_que.s_arr[my_que.s_tail]= rand ()% + ; My_que.s_tail= (My_que.s_tail +1)% (CNT +1) ; if(que_cnt (&my_que) = =1) {Pthread_cond_broadcast (&Cond_con); } printf ("produce a product, total num:%d \ n", Que_cnt (&my_que)); Pthread_mutex_unlock (&mutex); Sleep (rand ()%3+1); }}void* Con_handler (void*Arg) {Pthread_detach (pthread_self ()); while(1) {Pthread_mutex_lock (&mutex); while(Que_empty (&My_que)) {pthread_cond_wait (&cond_con, &mutex); } My_que.s_front= (My_que.s_front +1)% (CNT +1) ; if(que_cnt (&my_que) = = CNT-1) { /*since our main thread is to create a producer thread after the consumer thread is created, all consumer threads are suspended at the beginning and queued in the condition variable Cond_pro so that all consumer threads need to be notified with broadcast. Otherwise, a producer thread is notified, and the consumer thread grabs the lock. Of course, if the first mainline enters upgradeable creates a producer thread and then creates a consumer thread, because the producer threads are not all blocked, you can use signal to wake up a*/Pthread_cond_broadcast (&Cond_pro); } printf ("consume a product, total num:%d \ n", Que_cnt (&my_que)); Pthread_mutex_unlock (&mutex); Sleep (rand ()%3+1); }}intMainintargcChar* argv[])//exe Pro_num con_num{ intcon_cnt, pro_cnt; My_que.s_front=0 ; My_que.s_tail=0 ; Pro_cnt= Atoi (argv[1]) ; Con_cnt= Atoi (argv[2]) ; Srand (Getpid ()); Pthread_mutex_init (&mutex, NULL); Pthread_cond_init (&Cond_pro, NULL); Pthread_cond_init (&Cond_con, NULL); pthread_t* arr = (pthread_t*) calloc (con_cnt + pro_cnt,sizeof(pthread_t)); intindex =0 ; while(Con_cnt >0) {pthread_create (arr+index, NULL, Con_handler, NULL); Index++ ; Con_cnt-- ; } Sleep (5); while(Pro_cnt >0) {pthread_create (arr+index, NULL, Pro_handler, NULL); Index++ ; Pro_cnt-- ; } while(1) ; Pthread_mutex_destroy (&mutex); Pthread_cond_destroy (&Cond_pro); Pthread_cond_destroy (&Cond_con); return 0 ;}
Makefile
main:main.c -O [email protected] $<-lpthread
Linux multi-thread synchronization 2--producer consumer model