In Windows, semaphores are used to solve producer and consumer problems.

Source: Internet
Author: User
# Include <windows. h> # include <fstream> // different from textbooks # include <iostream> // different from textbooks # include <string> # include <conio. h> using namespace STD; // defines some constants; // The maximum number of critical sections allowed by this program; # define max_buffer_num10 // The multiplication factor in seconds to milliseconds; # define inte_per_sec 1000 // The total number of Production and Consumption threads allowed by this program; # define max_thread_num 64 // defines a structure, record the parameter struct threadinfo {intserial; // The thread serial number charentity; // P or cdoubledelay; // specifies the thread delay intthread_request [max_thread_num]; // thread Request queue int N_request; // number of requests}; // global variable definition // critical area object declaration, used to manage mutually exclusive access to the buffer zone; critical_sectionpc_critical [max_buffer_num]; int buffer_critical [max_buffer_num]; // buffer declaration, used to store products; handle h_thread [max_thread_num]; // array used to store each thread handle; threadinfothread_info [max_thread_num]; // thread information array; handleempty_semaphore; // a semaphore; handleh_mutex; // A mutex; dwordn_thread = 0; // the actual number of threads; dwordn_buffer_or_critical; // the actual number of buffer or critical zone; handleh_semaphore [max_thread _ Num]; // The semaphore that the producer allows the consumer to start consuming; // The Void produce (void * P) declared for production consumption and helper functions; void consume (void * P ); bool ifinotherrequest (INT); int findproducepositon (); int findbufferposition (INT); int main (void) {// declare the required variable; dwordwait_for_all; ifstreaminfile; // initialize the buffer; for (INT I = 0; I <max_buffer_num; I ++) buffer_critical [I] =-1; // initialize the Request queue for each thread; For (Int J = 0; j <max_thread_num; j ++) {for (int K = 0; k <max_thread_num; k ++) thread_info [J]. thread_request [K] =-1; thread_info [J]. n_request = 0;} // initialize the critical section; For (INT I = 0; I <max_buffer_num; I ++) initializecriticalsection (& pc_critical [I]); // open the input file, extracts information such as threads in the specified format. infile. open ("test.txt"); // obtain the actual number of buffers from the file; infile> n_buffer_or_critical; n_buffer_or_critical = infile. get (); printf ("input file: \ n"); // The number of buffers obtained by ECHO; printf ("% d \ n", (INT) n_buffer_or_critical); // extract information of each thread to the corresponding data structure; while (infile) {infile> thread_info [n_thread ]. Serial; infile> thread_info [n_thread]. entity; infile> thread_info [n_thread]. Delay; char C; infile. Get (c); While (C! = '\ N '&&! Infile. EOF () {infile> thread_info [n_thread]. thread_request [thread_info [n_thread]. n_request ++]; infile. get (c) ;}n_thread ++;} // The thread information obtained by ECHO, which is easy to confirm. For (Int J = 0; j <(INT) n_thread; j ++) {int temp_serial = thread_info [J]. serial; char temp_entity = thread_info [J]. entity; double temp_delay = thread_info [J]. delay; printf ("\ n thread % 2D % C % F", temp_serial, temp_entity, temp_delay); int temp_request = thread_info [J]. N _ Request; For (int K = 0; k <temp_request; k ++) printf ("% d", thread_info [J]. thread_request [k]); cout <Endl;} printf ("\ n"); // create several necessary semaphores in the simulation process: empty_semaphore = createsemaphore (null, n_buffer_or_critical, n_buffer_or_critical, null); h_mutex = createmutex (null, false, null ); // The following cycle uses the thread ID to name the synchronous semaphores used for product read/write of the corresponding production thread. For (Int J = 0; j <(INT) n_thread; j ++) {STD: String Lp = "semaphore_for_produce _"; int temp = J; while (temp) {ch Ar c = (char) (TEMP % 10); LP + = C; temp/= 10;} h_semaphore [J + 1] = createsemaphore (null, 0, n_thread, null) ;}// create producer and consumer threads; For (INT I = 0; I <(INT) n_thread; I ++) {If (thread_info [I]. entity = 'P') h_thread [I] = createthread (null, 0, (lpthread_start_routine) (produce), & (thread_info [I]), 0, null ); elseh_thread [I] = createthread (null, 0, (lpthread_start_routine) (consume), & (thread_info [I]), 0, null );} // The main program waits for the action of each thread to end; wait_for_all = Wai Tformultipleobjects (n_thread, h_thread, true,-1); printf ("\ n all producers and consumers have completed their work. \ n "); printf (" press any key to return! \ N "); _ getch (); Return 0 ;}// check whether any consumption request to the same product is not executed; bool ifinotherrequest (INT req) {for (INT I = 0; I <n_thread; I ++) for (Int J = 0; j <thread_info [I]. n_request; j ++) if (thread_info [I]. thread_request [J] = req) return true; return false;} // locate the empty buffer location currently available for product production; intfindproduceposition () {int emptyposition; for (INT I = 0; I <n_buffer_or_critical; I ++) if (buffer_critical [I] =-1) {emptyposition = I; // use the following special value to indicate that the buffer is being written. buffer_c Ritical [I] =-2; break;} return emptyposition;} // locate the position of the product to be produced by the current producer; int findbufferposition (INT propos) {int temppos; for (INT I = 0; I <n_buffer_or_critical; I ++) if (buffer_critical [I] = propos) {temppos = I; break;} return temppos ;} // producer process void produce (void * P) {// local variable Declaration; dwordwait_for_semaphore, wait_for_mutex, m_delay; intm_serial; // obtain the thread information; m_serial = (threadinfo *) (p)-> serial; m_delay = (DWORD) (threadinfo *) (P )-> Delay * inte_per_sec); sleep (m_delay); // start the request to produce printf ("producer % 2D sends the production request signal. \ n ", m_serial); // confirm that the free buffer zone is available for production, and reduce the number of empty locations by 1; for synchronization between producers and consumers; wait_for_semaphore = waitforsingleobject (empty_semaphore, -1); // mutually exclusive access to the next blank critical section that can be used for production, to achieve mutually exclusive write and write; wait_for_mutex = waitforsingleobject (h_mutex,-1); int producepos = findproduceposition (); releasemutex (h_mutex); // After the producer obtains its own null position and marks it, the following write operations can be performed concurrently among the producers; // In the core production step, the program uses the producer ID as the product number to facilitate consumer recognition. Don't; printf ("producer % 2D starts producing products in buffer % 2D. \ n ", m_serial, producepos); buffer_critical [producepos] = m_serial; printf (" producer % 2D finished production process: \ n ", m_serial ); printf ("buffer [% 2D]: % 3d \ n", producepos, buffer_critical [producepos]); // enable the buffer written by the producer to be used by multiple consumers, implement read/write synchronization; releasesemaphore (h_semaphore [m_serial], n_thread, null);} // void consume (void * P) of the consumer process {// local variable Declaration; dwordwait_for_semaphore, m_delay; intm_serial, m_requestnum; // the serial number of the consumer thread and The number of requests; intm_thread_request [max_thread_num]; // The Request queue of the local consumer thread; // extract the information of the local thread to the local machine; m_serial = (threadinfo *) (p )) -> serial; m_delay = (DWORD) (threadinfo *) (p)-> delay * inte_per_sec); m_requestnum = (threadinfo *) (p )) -> n_request; For (INT I = 0; I <m_requestnum; I ++) m_thread_request [I] = (threadinfo *) (p)-> thread_request [I]; sleep (m_delay); // cyclically consume the required products for (INT I = 0; I <m_requestnum; I ++) {// request to consume the next product printf ("Consumer % 2D request to consume % 2D product \ n ", m_serial, m_thread_request [I]); // if the corresponding producer does not produce, wait; If the producer is produced, the number of consumers allowed is-1; implement read/write synchronization; wait_for_semaphore = waitforsingleobject (h_semaphore [m_thread_request [I],-1 ); // query the number of products in the buffer zone int bufferpos = findbufferposition (m_thread_request [I]); // start the consumption Processing of the specific buffer zone, the read and read operations are mutually exclusive in the buffer zone. // after entering the critical section, the system executes the Consumption Action. After completing the request, it notifies another consumer that the request has been met; at the same time, if the corresponding product is used up, the corresponding processing will be done; and the interface for corresponding actions will be provided // display; the corresponding processing means clearing the corresponding buffer zone, and add a semaphore representing the empty buffer; entercriticalsection (& pc_cri Tical [bufferpos]); printf ("Consumer % 2D starts to consume % 2D product \ n", m_serial, m_thread_request [I]); (threadinfo *) (p )) -> thread_request [I] =-1; if (! Ifinotherrequest (m_thread_request [I]) {buffer_critical [bufferpos] =-1; // flag the buffer is empty; printf ("Consumer % 2D successfully consumed % 2D: \ n ", m_serial, m_thread_request [I]); printf ("buffer [% 2D]: % 3d \ n", bufferpos, buffer_critical [bufferpos]); releasesemaphore (empty_semaphore, 1, null);} else {printf ("Consumer % 2D successfully consumed product % 2D \ n", m_serial, m_thread_request [I]);} // leave the critical section leavecriticalsection (& pc_critical [bufferpos]);}

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.