I. Basic knowledge
1.1 The difference between the semaphore of the System V version and the POSIX down-signal volume
We've talked about the three forms of interprocess communication: Pipelines, message queues, semaphores. This semaphore, which is in the System V version, is requested in the form of a semaphore set, which identifies whether a critical resource is present or not, thereby controlling the ability of different processes to access the critical resource. But now, the semaphore we're going to talk about is based on the semaphore under POSIX, which is used to identify the number of resources.
1.2 Mutual exclusion Lock and semaphore
as described in the previous article, mutex (mutex) can be seen as a usable number of some kind of resource, The mutex variable is 0, or 1, and the mutex at initialization is 1, which indicates that there is one available resource, the resource is obtained when locking, the mutex is reduced to 0, the resource is no longer available, the resources are freed when unlocked, and the mutex is added to 1, indicating that another resource is available.
that is, semaphores and mutexes Act Similarly, indicating the number of available resources, unlike mutexes, where the amount of semaphores can be greater than 1.
If the semaphore describes the number of resources is 1 o'clock, this time the semaphore is the same as the mutual repulsion lock!
This semaphore can be used not only for synchronization between threads in the same process, but also for synchronization between different processes.
Two. Related functions
2.1 Initialization
650) this.width=650; "src=" Http://s1.51cto.com/wyfs02/M02/7F/60/wKioL1cclRfwj8OhAAAeIbLxH5E257.png "title=" capture. PNG "alt=" Wkiol1cclrfwj8ohaaaeiblxh5e257.png "/>
The type of the semaphore variable is sem_t,sem_init () to initialize a semaphore variable,
Pshared: A parameter of 0 indicates that the semaphore is used for inter-thread synchronization of the same process
Value: The number of available resources
2.2 Releasing Resources
650) this.width=650; "src=" Http://s4.51cto.com/wyfs02/M02/7F/60/wKioL1cco_yBeoz2AAAZ6bdz1gU503.png "title=" capture. PNG "alt=" Wkiol1cco_ybeoz2aaaz6bdz1gu503.png "/>
2.3 P, v operation
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M01/7F/63/wKiom1ccok_A1kosAAAoFPKITfc371.png "title=" capture. PNG "alt=" Wkiom1ccok_a1kosaaaofpkitfc371.png "/>
Sem_wait (): Gets the resource (P action-1), which causes the value of semaphore to be reduced by 1, and if the value of semaphore is already 0 when calling Sem_wait (), the wait is suspended. If you do not want to suspend the wait, you can call Sem_trywait ().
Sem_post (): Frees the resource (v operation + 1), adds 1 to the value of semaphore, and wakes up the thread waiting to be suspended.
Three. Related code (multi-producer multi-consumer model)
test.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 #include <semaphore.h> 5 6 #define max 20 7 static pthread_mutex_t lock=pthread_ mutex_initializer; 8 sem_t blank; 9 sem_t data; 10 11 int buf[max]; 12 13 void* product (Void* arg) 14 { 15 int i=0; 16 int index=0; 17 while (1) 18 { 19 sem_wait (&blank); 20 pthread_mutex_lock (&lock); 21 buf[index++] =i++; 22 index%=max; 23 printf ("product%d done...val is :%d\n", (int) arg,i-1); 24 sem_post (&data); 25 pthread_mutex_unlock (&lock); 26 sleep (2); 27 } 28 } 29 void* consumer (Void* arg) 30 { 31 int index=0; 32 while (1) 33 { 34 sem_wait ( &data); 35 pthread_mutex_lock (&lock); 36 int val=buf[index++]; 37 index%=max; 38 printf ("consumer%d Done...val is:%d\n ", (int) arg,val); 39 sem_post ( &blank); 40 pthread_mutex_unlock (&lock); 41 sleep (1); 42 } 43 } 44 int main () 45 { 46 sem_init ( &blank,0,max); 47 sem_init (&data,0,0); 48 49 pthread_t product1; 50 pthread_t product2; 51 pthread_t product3; 52 pthread_t consumer1; 53 pthread_t consumer2; 54 pthread_t cOnsumer3; 55 56 pthread_create (&product1,NULL,product, (void*) 1); 57 pthread_create (&product2,null,product, (void*) 2); 58 pthread_create (&product3,null,product, (void*) 3); 59 pthread_create (&consumer1,null,consumer, (void*) 1); 60 pthread_ Create (&consumer2,null,consumer, (void*) 2); 61 pthread_create (& Consumer3,null,consumer, (void*) 3); 62 63 pthread_join (Product1, NULL); 64 pthread_join (Product2,null); 65 Pthread_join (Product3,null); 66 pthread_join (Consumer1,NULL); 67 pthread_join (Consumer2,null); 68 pthread_join ( Consumer3,null); 69 &nbsP;70 sem_destroy (&blank); 71 sem_destroy ( &data); 72 73 pthread_mutex_destroy (&lock); 74 75 return 0; 76 } // Makefile 1 test:test.c 2 gcc -o [email protected] $^ -lpthread 3 . Phony:clean 4 clean: 5 rm -f test
Output Result:
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M02/7F/61/wKioL1ccuwPRWU6xAABCPRQ6p2E452.png "title=" capture. PNG "alt=" Wkiol1ccuwprwu6xaabcprq6p2e452.png "/>
Four. Analysis and summary
1) Single production but the consumer model, because P, v operation has been ordered by the two, equivalent to complete the synchronization and mutual exclusion (the above code implementation to remove lock unlock that is the 20,25,35,40 line); multi-producer multi-consumer model, that is, the above code implementation. (There is mutual exclusion between producers and producers because of mutual exclusion between consumers and consumers.)
2) There is one more way to unlock locking, which is added before sem_wait, but this can cause deadlock problems: if the consumer enters first, applies for data, and the producer that produces data at this time is suspended waiting.
This article is from the "sunshine225" blog, make sure to keep this source http://10707460.blog.51cto.com/10697460/1767300
Realization of producer consumption model based on POSIX signal volume