Linux multithreaded simulation producer/consumer issues

Source: Internet
Author: User

description :

Producer - consumer problem is a classic process synchronization problem, which was first proposed by Dijkstra to demonstrate the semaphore mechanism he proposed. n Thread producer threads that execute within the same process address space produce items and then place the items in an empty buffer for consumption by n consumer threads. The consumer thread obtains the item from the buffer and then releases the buffer. When a producer thread produces an item, if no empty buffers are available, the producer thread must wait for the consumer thread to release an empty buffer. When consumer threads consume items, if there is no full buffer, then the consumer thread will be blocked until the new item is produced.

Input:

Number of producers, number of consumers, buffer size, number of products produced per producer, etc.


Output:

Producer - consumer concurrent execution process. Consumers end up spending all of their products.

Code implementation:

Main.cpp#include "Storage.h"//code as follows # include <signal.h> #include <pthread.h> #include <unistd.h># Include <string.h> #include <stdio.h> #include <stdio.h> #include <iostream>using namespace std   ; const int sleeptime = 1;struct passstruct{pthread_mutex_t *m_mutex;            The mutex that is shared by all threads int *m_products;         The number of products produced by producers Storage *m_storage;          shared storage int *m_nthreadnum; Thread label};p thread_cond_t notempty;pthread_cond_t notfull;void *producer (void *arg) {//Gets the value from the control thread passstruct tmp = *    Static_cast<passstruct *> (ARG);    The number of products produced per producer int *products = tmp.m_products;    Controls the amount of mutex that has been initialized in the thread pthread_mutex_t *mutex = Tmp.m_mutex;    Get warehouse Storage *storage = tmp.m_storage;    Char strtostore[128],strcurrentstored[128];    sprintf (Strtostore, "\tadd%d product to storage...\n", *products);        while (true) {//Gets the mutex pthread_mutex_lock (mutex); If the current warehouse is full (there is no space to populate), the print blocking message if (!storage-> Ishavespace ()) {cout << "+ + producer" << * (tmp.m_nthreadnum) << "block\n" <            < Endl;        Wait for the condition variable, and release the Mutex pthread_cond_wait (? full,mutex);        }//There is already room in the warehouse, sleep for a while before the production of Sleep (sleeptime);        Print activation message cout << "+ producer" << * (tmp.m_nthreadnum) << "Activate" << Endl;        Started production of product write (Stdout_fileno,strtostore,strlen (Strtostore));        Storage, Addtostorage (*products); Print the total number of products in the current warehouse sprintf (strcurrentstored, "\t\tcurrent storage%d products\n\n", storage-CurrentC        Ount ());        Write (Stdout_fileno,strcurrentstored,strlen (strcurrentstored));        Notifies the first consumer thread that waits for Semaphore Notempty, the current warehouse is non-empty pthread_cond_signal (? empty);        Pthread_mutex_unlock (mutex);    Sleep for a while in the next round of competition sleep (sleeptime); } pthread_exit (NULL);}    void *consumer (void *arg) {passstruct tmp = *static_cast<passstruct *> (ARG); Pthread_mutex_t *mutex = Tmp.m_mutex;    Storage *storage = tmp.m_storage;    String Strtodisplay ("\tget a Product from storage...\n");    Char strcurrentstored[128];        while (true) {//Gets the mutex pthread_mutex_lock (mutex); Empty in the current warehouse (no products in the warehouse), print a blocking message and wait for the conditional variable to arrive if (!storage-ishaveproduct ()) {cout << "-Con            Sumer "<< * (tmp.m_nthreadnum) <<" block\n "<< Endl;        Pthread_cond_wait (? empty,mutex);        }//The current warehouse already has the product ^ ^, first sleep a while in the consumption of sleep (sleeptime);        Print activation message cout << "-Consumer" << * (tmp.m_nthreadnum) << "Activate" << Endl;        Write (Stdout_fileno,strtodisplay.c_str (), strtodisplay.size ());        Storage, getfromstorage (); Print the number of products in the current warehouse sprintf (strcurrentstored, "\t\tcurrent storage%d products\n\n", storage-CurrentC        Ount ());        Write (Stdout_fileno,strcurrentstored,strlen (strcurrentstored)); Inform the first block of the notfull conditionThe producer thread of the variable, the current warehouse already has the space pthread_cond_signal (? full);        Pthread_mutex_unlock (mutex);    Go to sleep for a while and then compete in the competition Sleep (sleeptime); } pthread_exit (NULL);}    Signal capture function void onsignal (int signalnumber) {switch (Signalnumber) {///if snapping to SIGUSR1, the entire program exits, SIGUSR1 is generated by the STOP.SH program        Case Sigusr1:cout << ' Main program ending ... ' << Endl;        _exit (0);    Break Case Sigint:cout << "Can ' t Kill the program with CTRL + C, please use the Shell Script stop.sh!" << Endl        ;        Sleep (5);    Break    Default:break;    }}int Main () {//Registered signal signal (sigusr1,onsignal);    Signal (sigint,onsignal);    Freopen ("Back.txt", "w", stdout);    Initialize the mutex and the condition variable pthread_mutex_t *mutex = new pthread_mutex_t;    Pthread_mutex_init (Mutex,null);    Pthread_cond_init (? empty,null);    Pthread_cond_init (? full,null);    int numberofproducer;    cout << "Please input the number of Producer:";    Cin >> Numberofproducer; int NumberoFconsumer;    cout << "Please input the number of Consumer:";    Cin >> Numberofconsumer;    int numberofproducts;    cout << "Please input the number of products for one PRODUCER:";    Cin >> Numberofproducts;    int sizeofstorage;    cout << "Please input the size of the Storage:";    Cin >> Sizeofstorage;    Storage Storage (sizeofstorage);    Initializes the value passed by Passstruct Passvalue;    Passvalue.m_mutex = Mutex;    Passvalue.m_products = &numberOfProducts;    Passvalue.m_storage = &storage;    pthread_t Pthreadproducer,pthreadconsumer;        for (int i = 0; I! = Numberofconsumer; ++i) {passvalue.m_nthreadnum = new int (i+1);    Pthread_create (&pthreadconsumer,null,consumer, static_cast<void *> (&passvalue));        } for (int i = 0; I! = Numberofproducer; ++i) {passvalue.m_nthreadnum = new int (i+1); Pthread_create (&pthreadproducer,null,producer, Static_cAst<void *> (&passvalue));    }//wait for thread to end Pthread_join (pthreadproducer,null);    Pthread_join (Pthreadconsumer,null);    Pthread_mutex_destroy (mutex);    Delete Mutex;    Pthread_cond_destroy (? empty);    Pthread_cond_destroy (? full); return 0;}

Storage.h#ifndef storage_h_included#define storage_h_includedclass storage{public:    Storage (int);    ~storage ();    int Currentcount ()    {        return hasbeenstored;    }    BOOL Ishavespace ()    {        if (hasbeenstored < buffersize)        {            return true;        }        return false;    }    BOOL Ishaveproduct ()    {        if (hasbeenstored! = 0)        {            return true;        }        return false;    }    BOOL IsEmpty ()    {        return hasbeenstored = = 0    ;    } void Addtostorage (int n);    void Getfromstorage ();p rivate:    int buffersize;    int hasbeenstored;}; #endif//storage_h_included

Storage.cpp#include "Storage.h" storage::storage (int n = 0): buffersize (n), hasbeenstored (0) {}storage::~storage () {} void Storage::addtostorage (int n) {    if (hasbeenstored + n > buffersize)        hasbeenstored = buffersize;    else        hasbeenstored + = n;} void Storage::getfromstorage () {    if (!isempty ())        --hasbeenstored;    else        hasbeenstored = 0;}

attached (Makefile, startup scripts, etc.):

MAKEFILECC = G++cppflags =-wall-g-pthreadsources = $ (wildcard *.cpp) OBJECTS = $ (SOURCES:.CPP=.O) BIN = Main. Phony:all Cleanall: $ (BIN) $ (BIN): $ (OBJECTS) $ (CC) $ (cppflags)-o [email protected] $^ @echo "# # # # # # # ok! # # # # # #%.O:%.cpp$ (CC) $ (cppflags)-C $^-o [email protected]clean:-rm-rf $ (BIN) $ (OBJECTS) *.CBP *.layout

startup script for main program

#!/bin/bash# A Shell Script for Start, the main programbin=mainisexist=$ (/bin/ls |/bin/grep main$) #if This program is not Exi TS, make It.if ["$ISEXIST" = ""]; then/usr/bin/makefi#if This program is not running, start it. pid=$ (/usr/bin/pgrep $BIN) if ["$PID" = ""]; Then./mainfi

termination script for main program

#!/bin/bash# A Shell Script for Stop the main programpid=$ (/usr/bin/pgrep main) if ["$PID"! = ""]; THEN/BIN/KILL-USR1 $PID # Send SIGUSR1 signal to main program fi




Linux multithreaded simulation producer/consumer issues

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.