Thread synchronization and mutex (POSIX semaphore--ring array implementation producer consumer model)

Source: Internet
Author: User
Tags mutex posix semaphore

Semaphore (semaphore)


The mutex variable is 0 or 1, which can be considered as the available quantity of a resource, and the mutex is 1 when initialized, indicating that there is an available resource, the resource is locking, the mutex is reduced to 0, the resource is no longer available, the resource is freed when unlocked, and the mutex is added to 1, indicating that there is another available resource.


Semaphores (Semaphore) are similar to mutexes, which indicate the number of available resources, unlike mutexes, which can be greater than 1. If the semaphore describes the number of resources is 1 o'clock, at this time the semaphore and the same mutex lock!


POSIX Semaphore library functions, which can be used not only for synchronization between threads of the same process, but also for synchronization between different processes.



About functions:


650) this.width=650; "src=" Http://s5.51cto.com/wyfs02/M02/7F/51/wKiom1cZuMHiB4LEAAAbDPYbGcg032.png "title=" 0.PNG " alt= "Wkiom1czumhib4leaaabdpybgcg032.png"/>


Single producer but consumer model:

Code Description:

Data for 1.push () and Pop () (datatype) This article uses the basic type, and if it is a custom type, you need to implement the overload of the assignment operator

2. The array is actually linear, there is no ring array in memory, we define a fixed-size array, when the last element of the array is also filled with data, check whether the first element of the array (subscript 0 Element) has been read by the consumer, if already read, then the producer can continue to put the data, When the array is full (that is, the elements in the array are not read by the consumer), the producer Waits.

3.sem_init () initializes two semaphore sem_p (control producer) and Sem_c (Control consumer), pshared to 0 o'clock, indicating that semaphores are used for inter-thread synchronization of the same process

Sem_destroy () returns two semaphores to the pre-initialized state

Sem_wait () can obtain resources, equivalent to P operations, to reduce the given signal volume by one

Sem_post () Can free up resources, which is equivalent to V operation, plus one operation

When the semaphore value is 0 o'clock, sem_wait () suspends the process and waits, sem_trywait () does not suspend the process


Code implementation:

Ring.cpp

#include  <iostream> #include  <stdlib.h> #include  <semaphore.h> #include   <pthread.h>using namespace std; #define  sem_pro 20#define sem_con 0#define  size sem_protypedef int datatype; datatype ring[size];//the definition of an array datatype pro, Con;sem_t sem_p;//productsem_t sem_c;//consumervoid init_ring (datatype  (*ring) [SIZE]) {     pro=0;    con=0; }datatype& push (datatype & Data,int index) {    ring[pro++]=data;    datatype tmp=ring[ Pro-1];    pro%=size;    return tmp;} Datatype& pop (int index) {    con++;    datatype tmp =ring[con-1];    con%=size;    return tmp;} Void* product (Void* arg) {    while (1) {&Nbsp;       datatype data=rand ()%50;         sem_wait (&sem_p);         datatype val=push ( Data,pro);        cout<< "Product done...,val is:" < <val<<endl;        sem_post (&sem_c);         sleep (1);     }}void* consumer (Void* arg) {     while (1) {        sem_wait (&sem_c);         datatype val=pop (Con);         cout<< "Consumer done...,val is:" <<val<<endl;         sem_post (&sem_p);         sleep (8);     }}int main () {&NBsp;   init_ring (&ring);     sem_init (&sem_p,0,sem_pro);     sem_init (&sem_c,0,0);    pthread_t tid1,tid2;     Pthread_create (&tid1,null,product,null);     pthread_create (&tid2,NULL,consumer, NULL);     sem_destroy (&sem_p);     sem_destroy (&sem_c);     pthread_join (Tid1,null);     pthread_join (Tid2,NULL);     return 0;}

Makefile

Ring:ring.cpp g++-o [email protected] $^-lpthread. PHONY:CLEANCLEAN:RM-F Ring


The speed of the following two run producers and consumers has changed, resulting in a different running result

First Run Result:

650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M00/7F/50/wKioL1cZzb-Qplo2AAAcqa33rBQ313.png "style=" float: none; "title=" 1.PNG "alt=" Wkiol1czzb-qplo2aaacqa33rbq313.png "/>

Second run Result:

650) this.width=650; "src=" Http://s5.51cto.com/wyfs02/M01/7F/52/wKiom1cZzQDg9zHLAAAfg8eKQfQ195.png "style=" float: none; "title=" 2.PNG "alt=" Wkiom1czzqdg9zhlaaafg8ekqfq195.png "/>


Multi-producer Multi-consumer model: (in fact, like single-producer single-Consumer, only add 6 lines of thread-created and waiting code)

#include  <iostream> #include  <stdlib.h> #include  <semaphore.h> #include   <pthread.h>using namespace std; #define  sem_pro 20#define sem_con 0#define  size sem_protypedef int datatype;datatype ring[size];d atatype pro,con;sem_t  sem_p;//productsem_t sem_c;//consumervoid init_ring (datatype  (*ring) [SIZE]) {     pro=0;    con=0;} Datatype& push (Datatype &data,int index) {    ring[pro++]=data;     datatype tmp=ring[pro-1];    pro%=SIZE;     return tmp;} Datatype& pop (int index) {    con++;    datatype tmp =ring[con-1];    con%=size;    return tmp;} Void* product (Void* arg) {    while (1) {&NBSP;&NBSP;&NBSP;&NBsp;    datatype data=rand ()%50;        sem_ Wait (&sem_p);         datatype val=push (Data,pro);         sem_wait (&sem_p);         Datatype val=push (Data,pro);        cout<< "Product" << (int) arg<< " done...,val is:" <<val<<endl;         sem_post (&sem_c);         sleep (1);     }} Void* consumer (Void* arg) {    while (1) {         sem_wait (&sem_c);         datatype val=pop (con);         cout<< "Consumer" << (int) arg<< " done ..., Val is: "<<val<<endl;        sem_post (&sem_p);         sleep (3);     }}int main () {    init_ring ( &ring);     sem_init (&sem_p,0,sem_pro);     sem_init (&sem_c, 0,0);     pthread_t tid1,tid2,tid3;    pthread_create (&AMP;TID1, Null,product, (void*) 1);     pthread_create (&tid2,null,product, (void*) 2);     pthread_create (&tid3,null,product, (void*) 3);    pthread_t tid4,tid5;     pthread_create (&tid4,null,consumer, (void*) 4);     pthread_ Create (&tid5,null,consumer, (void*) 5);     sem_destroy (&sem_p);     sem_destroy (&sem_c);     pthread_join (tid1,null);     pthread_ Join (tid2,null);   &Nbsp; pthread_join (Tid3,null);     pthread_join (Tid4,null);     Pthread_join (tid5,null);     return 0;}

Operation Result:

650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M00/7F/51/wKioL1cZ09GigGZpAAAqYGv9UIw854.png "title=" 0.PNG " alt= "Wkiol1cz09giggzpaaaqygv9uiw854.png"/>

This article is from the "Zero Egg" blog, please be sure to keep this source http://lingdandan.blog.51cto.com/10697032/1766740

Thread synchronization and mutex (POSIX semaphore--ring array implementation producer consumer model)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.