Linux multithreaded Practice (5)--posix signal volume and mutex to solve the problem of producer consumers

Source: Internet
Author: User
Tags posix semaphore

POSIX signal Volume

Posix Signal Volume

Well-known signal volume

Nameless semaphore

Sem_open

Sem_init

Sem_close

Sem_destroy

Sem_unlink

Sem_wait

Sem_post

Well-known signal volume

#include <fcntl.h>/           * for o_* constants */#include <sys/stat.h>/        * for Mode constants */#include < semaphore.h>sem_t *sem_open (const char *name, int oflag); sem_t *sem_open (const char *name, int oflag, mode_t mode, Unsi gned int value); int sem_close (sem_t *sem); int sem_unlink (const char *name);

similar to the POSIX class IPC usage: The name is identified in/somename form and can only have one/, and the total length cannot exceed name_max-4 (i.e, 251).

POSIX-known semaphores need to be created or opened with the Sem_open function, and the PV operation is sem_wait and Sem_post, which can be closed using sem_close and deleted with Sem_unlink.

A well-known semaphore is used for inter-process synchronization (which can be accessed by name) that does not require shared memory, similar to the system V semaphore.

Anonymous signal Volume

#include <semaphore.h>int sem_init (sem_t *sem, int pshared, unsigned int value); int Sem_destroy (sem_t *sem);

The anonymous semaphore only exists in memory and requires that the process that uses the semaphore must have access to the memory; This means that they can only apply to threads in the same process, or to threads in different processes that have mapped the same memory content into their address space.

The anonymous semaphore must be initialized with Sem_init, and the second parameter of the Sem_init function pshared determines whether thread sharing (pshared=0) or process sharing (pshared!=0) can also be used with Sem_post and sem_wait , the anonymous semaphore is destroyed first with Sem_destroy before the shared memory is released.

POSIX Semaphore PV operation

int sem_wait (sem_t *sem);//p operation int Sem_post (sem_t *sem);//v operation

The wait operation achieves a minus 1 of the semaphore, and if the semaphore count is 0, it will block.

The post operation increases the semaphore by 1, and when calling Sem_post, if a process block occurs in the call sem_wait, the process is awakened and the semaphore count of Sem_post 1 is again sem_wait minus 1;

POSIX mutual exclusion lock
#include <pthread.h>int pthread_mutex_init (pthread_mutex_t *mutex,                        const pthread_mutexattr_t *mutexattr) ;//Mutex initialization, note: After the function executes successfully, the mutex is initialized to an unlocked state. int Pthread_mutex_lock (pthread_mutex_t *mutex);//Mutex lock int pthread_mutex_trylock (pthread_mutex_t *mutex);// The mutex is judged by the lock int pthread_mutex_unlock (pthread_mutex_t *mutex);//Mutex unlock int Pthread_mutex_destroy (pthread_mutex_t *mutex); /elimination of mutual exclusion lock

A mutex is a simple locking method that controls atomic operations on shared resources. There are only two states of this mutex, that is, lock /unlock , which can be considered as a global variable in a sense. only one thread can master a mutex at the same time , and a locked thread can operate on the shared resource. If another thread wants to lock a mutex that has already been locked, the thread blocks until the locked thread releases the mutex. It can be said that this mutex guarantees that each thread will atomically manipulate the shared resources sequentially.

where a mutex can be divided into a quick mutex (default mutex), a recursive mutex, and a fault-checking mutex . The difference between these three types of locks is primarily in the fact that other threads that do not occupy the mutex need to block waiting when they want to obtain a mutex. A quick lock is a call thread that blocks until the line threads unlocked that owns the mutex. A recursive mutex can return successfully and increase the number of times the calling thread locks on the mutex, whereas a fault-checking mutex is a non-blocking version of the fast mutex, which returns immediately and returns an error message.

Producer Consumer issues

Use C + + to encapsulate buffers into class Storage

Storage Design class Storage{public:    Storage (unsigned int _buffersize);    ~storage ();    void consume (int id);   consumption    void produce (int id);   Production private:    //print buffer status    void display (bool Isconsumer = False);p rivate:    unsigned int buffsize;    int *m_storage; Buffer    unsigned short int in;  Production location    unsigned short int out;//consumption position    unsigned int product_number;    Product number    sem_t sem_full;//full semaphore    sem_t sem_empty;//empty signal    pthread_mutex_t mutex;  Mutex: Secure buffer mutex access};
//storage class implementation storage :: Storage (unsigned int _buffersize): Buffsize (_buffersize), in (0), out (0), Product_number (0) {m_storage = new Int[bu    Ffsize];    for (unsigned int i = 0; i < buffsize; + + i) m_storage[i] = 1;    Sem_init (&sem_full, 0, 0);    Initialize the empty semaphore to the buffer size sem_init (&sem_empty, 0, buffsize); Pthread_mutex_init (&mutex, NULL);}    Storage::~storage () {delete []m_storage;    Pthread_mutex_destroy (&mutex);    Sem_destroy (&sem_empty); Sem_destroy (&sem_full);} 
void Storage::p roduce (int id) {printf ("producer%d is waiting Storage not full\n", id);    Gets the empty Semaphore sem_wait (&sem_empty);    Gets the mutex Pthread_mutex_lock (&mutex); Production cout << "+ + producer" << ID << "begin produce" << ++product_number << ".    .. "<< Endl;    M_storage[in] = Product_number;    Print at this time buffer status display (FALSE);    in = (in+1)%buffsize;    cout << "producer" << ID << "End produce ... \ n" << Endl;    Release Mutex Pthread_mutex_unlock (&mutex);    Release full semaphore sem_post (&sem_full); Sleep (1);}    void storage::consume (int id) {printf ("Consumer%d is waiting Storage not empty\n", id);    Get full semaphore sem_wait (&sem_full);    Gets the mutex Pthread_mutex_lock (&mutex);    consumption int consume_id = M_storage[out]; cout << "-consumer" << ID << "Begin consume" << consume_id << "..." << E    Ndl    M_storage[out] =-1; Print thisWhen the buffer state is display (true);    out = (out+1)%buffsize;    cout << "consumer" << ID << "End consume ... \ n" << Endl;    Unlock Mutex Pthread_mutex_unlock (&mutex);    Release empty semaphore sem_post (&sem_empty); Sleep (1);}
void Storage:    :d Isplay (bool isconsme) {cout << "states: {";         for (unsigned int i = 0; i < buffsize; ++i) {if (isconsme && out = i) cout << ' # ';        else if (!isconsme && in = = i) cout << ' * ';        if (m_storage[i] = =-1) cout << "null";    else printf ("%-4d", M_storage[i]); } cout << "}" << Endl;} 
Producer, Consumer code implementation//buffer storage *storage;//producer-thread void *producer (void *args) {int id = * (int *) args;    Delete (int *) args;   while (1) storage->produce (ID); Production return NULL;}    Consumer-thread void *consumer (void *args) {int id = * (int *) args;    Delete (int *) args;   while (1) storage->consume (ID); consumption return NULL;}    Master thread int main () {int nproducer = 1;    int nconsumer = 2;    cout << "Please input the number of producer:";    Cin >> Nproducer;    cout << "Please input the number of consumer:";    Cin >> Nconsumer;    cout << "Please input the size of buffer:";    int size;    CIN >> size;    Storage = new storage (size);    pthread_t *thread = new Pthread_t[nproducer+nconsumer];    Create a consumer process for (int i = 0; i < Nconsumer; ++i) pthread_create (&thread[i], NULL, consumer, new int (i)); Create producer process for (int i = 0; i < nproducer; ++i) pthread_create (&thread[nconsumer+i], NULL, producer, new INT (i));    Wait for the thread to end for (int i = 0; i < Nproducer+nconsumer; ++i) Pthread_join (Thread[i], NULL);    Delete storage; delete []thread;}

Complete source code:http://download.csdn.net/download/hanqing280441589/8444613


Linux multithreaded Practice (5)--posix signal volume and mutex to solve the problem of producer consumers

Related Article

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.