Note that there are some explanatory texts on larger screens.

plurals
  1. POC - consumer/producer appears deadlock when producer bigger than buffer size
    text
    copied!<p>I have assignment to work on producer and consumer problem by use thread and semaphore. The task is that allow user to define # of producer,# of consumer and buffer size. The program always lock if producer reach the buffersize. But the requirement says if producer reach buffersiz the consumer thread should start and take things from buffer. I am out of idea how to fix this problem and my teacher refuse to help. I am a totally beginner of the C language, please give me some suggestion. Thank you very much</p> <p>My program can run when Producer = Consumer, or Producer &lt; Consumer, except Producer > Buffer Size, it seems to appear deadlock, and I think I understand the reason why but I don't know how to fix the code to let Consumer thread run first than back to Producer thread.</p> <p>Here is the running result when producer =3 consumer = 1 and buffersize = 2</p> <pre><code>./Task2 3 1 2 Producer 0 has started Producer 0:Put item 0. Producer 1 has started Producer 1:Put item 1. Producer 2 has started </code></pre> <p>The requirement says the result should looks like</p> <pre><code>Started Producer 0 has started Producer 0: Put item 0. Producer 1 has started Producer 1: Put item 1. Producer 2 has started Consumer 0 has started Consumer 0: Taked item 0. Producer 2: Put item 2. Terminated! </code></pre> <p>Here is my origional code, I have discard some input error check code</p> <pre><code>#include &lt;pthread.h&gt; #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;semaphore.h&gt; pthread_t *pid, *cid; void *producer(void *param); void *consumer(void *param); void init(); int Remove(); struct prot_buffer{ int Producer; int Consumer; int *buffer; int buffersize; int front; int rear; int item; sem_t mutex; sem_t slots; sem_t items; }b; main(int argc, char *argv[]){ int c1; b.Producer = atoi(argv[1]); b.Consumer = atoi(argv[2]); b.buffersize = atoi(argv[3]); init(); pid = (pthread_t *)malloc(b.Producer *sizeof(pthread_t)); cid = (pthread_t *)malloc(b.Consumer *sizeof(pthread_t)); for (c1=0; c1&lt; b.Producer; c1++){ printf("Producer %d has started\n", c1); pthread_create(&amp;(pid[c1]),NULL, producer, NULL); pthread_join(pid[c1], NULL); printf("Producer %d:Create item %d.\n", c1,c1); } /* Create the consumer threads */ for (c1=0; c1&lt;b.Consumer; c1++){ printf("Consumer %d has started\n", c1); pthread_create(&amp;(cid[c1]),NULL, consumer, NULL); if (b.front==b.rear){ printf("Terminated!\n"); exit(0); } pthread_join(cid[c1], NULL); printf("Consumer %d:Taked item %d.\n", c1, c1); } free(b.buffer); free(pid); free(cid); sem_destroy(&amp;b.items); sem_destroy(&amp;b.slots); sem_destroy(&amp;b.mutex); printf("Threads terminated!\n"); exit(0); } void *producer(void *param){ sem_wait(&amp;b.slots); sem_wait(&amp;b.mutex); if(b.rear&lt;=b.buffersize){ b.buffer[b.rear] = b.item; b.rear++; sem_post(&amp;b.mutex); sem_post(&amp;b.items); }else{ sem_post(&amp;b.mutex); sem_post(&amp;b.items); } } void *consumer(void *param){ Remove(); } void init(){ b.buffer = (int *) malloc(b.buffersize *sizeof(int)); b.buffersize = b.buffersize; b.front = b.rear =0; sem_init(&amp;b.items, 0, 0); sem_init(&amp;b.slots,0,b.buffersize); sem_init(&amp;b.mutex, 0, 1); } int Remove(){ sem_wait(&amp;b.items); sem_wait(&amp;b.mutex); b.item = b.buffer[b.front]; b.front++; sem_post(&amp;b.mutex); sem_post(&amp;b.slots); return b.item; } </code></pre> <p>My new code</p> <pre><code>main(int argc, char *argv[]){ ... pthread_create(&amp;pid,NULL, producer, NULL); pthread_create(&amp;cid,NULL, consumer, NULL); .... } void *producer(void *param){ int c2; for (c2=0; c2 &lt; b.Producer; c2++) { printf("Producer %d has started\n", c2); b.item = c2; sem_wait(&amp;b.slots); sem_wait(&amp;b.mutex); b.buffer[b.rear] = b.item; b.rear = (b.rear+1)%b.buffersize; printf("Producer %d:Put item %d.\n", c2,c2); sem_post(&amp;b.mutex); sem_post(&amp;b.items); } return NULL; } void *consumer(void *param){ int c2; for (c2=0; c2 &lt; b.Consumer; c2++) { printf("Consumer %d has started\n", c2,c2); b.item = c2; sem_wait(&amp;b.items); sem_wait(&amp;b.mutex); b.buffer[b.front] = b.item; b.front = (b.front+1)%b.buffersize; printf("Consumer %d:take item %d.\n", c2, c2); sem_post(&amp;b.mutex); sem_post(&amp;b.slots); } return NULL; } </code></pre> <p>To avoid trobule at school I remove some code and some description.</p> <p>The program result is correct now, thanks for help. In this case I use b.item as the variable to display the item left inside the buffer, but its wrong. Use other variable like front or rear also not work too.</p> <p>Program result-</p> <p>Producer=2, Consumer=2, Buffer=2</p> <pre><code>./F 2 2 2 started Producer 0 has started Producer 0:Put item 0. Producer 1 has started Producer 1:Put item 1. Consumer 0 has started Consumer 0:Take item 0. Consumer 1 has started Consumer 1:Take item 1. 1 item(s) left in the buffer! //This is wrong! Terminated! </code></pre> <p>Producer=3, Consumer=1, Buffer=2</p> <pre><code>./F 3 1 2 started Producer 0 has started Producer 0:Deposited item 0. Producer 1 has started Producer 1:Deposited item 1. Producer 2 has started Consumer 0 has started Consumer 0:Removed item 0. Producer 2:Deposited item 2. 0 item(s) left in the buffer! //Still wrong! Terminated! </code></pre> <p>Producer =2, Consumer = 5, Buffer =3</p> <pre><code>./F 2 5 3 started Producer 0 has started Producer 0:Put item 0. Producer 1 has started Producer 1:Put item 1. Consumer 0 has started Consumer 0:Take item 0. Consumer 1 has started Consumer 1:Take item 1. Consumer 2 has started 2 item(s) left in the buffer! //Wrong again! Terminated! </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload