#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include <unistd.h>
char queueOfChars[ 10 ] ;
int number = 5 , buffer = 0 ;
sem_t fullsem, emptysem, producerSync, producerSync1, consumerSync, consumerSync1;
void producerPrinting( int i, char tmp, int p) {
printf ( "\n Producer#%d at i=%d : Inserted %c , buffer: %d" , p
, i
, tmp
, buffer
) ; }
char generateChar( ) {
sleep( 1 ) ;
return 'a' + ( ( rand ( ) * 100 ) % 26 ) ; }
void consumerProcess
( char * tmp
) { * tmp
= toupper ( * tmp
) ; }
void consumerPrinting( int i, char tmp, int c) {
printf ( "\n Consumer#%d at i=%d: Getting %c, buffer:%d" , c
, i
, tmp
, buffer
) ; }
void consumerRead( char * tmp) { * tmp = queueOfChars[ -- buffer] ; }
void insert( char e) {
if ( buffer < number)
queueOfChars[ buffer++ ] = e;
else
buffer = 0 ;
}
void * produce( void * a) {
int i;
for ( i = 0 ; i < number * 2 ; i++ ) {
sem_wait( & fullsem) ;
sem_wait( & producerSync1) ;
char tmp = generateChar( ) ;
insert( tmp) ;
producerPrinting( i, tmp, 1 ) ;
if ( buffer > number - 1 ) {
for ( int j = 0 ; j < number; ++ j) {
sem_post( & emptysem) ;
}
}
sem_post( & producerSync) ;
}
}
void * produce2( void * a) {
int i;
for ( i = 0 ; i < number * 2 ; i++ ) {
sem_wait( & fullsem) ;
sem_wait( & producerSync) ;
char tmp = generateChar( ) ;
insert( tmp) ;
producerPrinting( i, tmp, 2 ) ;
if ( buffer > number - 1 ) {
for ( int j = 0 ; j < number; ++ j) {
sem_post( & emptysem) ;
}
}
sem_post( & producerSync1) ;
}
}
void * consume( void * a) {
int i;
for ( i = 0 ; i < number * 2 ; i++ ) {
sem_wait( & emptysem) ;
sem_wait( & consumerSync1) ;
char tmp;
consumerRead( & tmp) ;
consumerProcess( & tmp) ;
consumerPrinting( i, tmp, 1 ) ;
if ( buffer == 0 ) {
for ( int j = 0 ; j < number; ++ j) {
sem_post( & fullsem) ;
}
}
sem_post( & consumerSync) ;
}
}
void * consume2( void * a) {
int i, v;
for ( i = 0 ; i < number * 2 ; i++ ) {
sem_wait( & emptysem) ;
sem_wait( & consumerSync) ;
char tmp;
consumerRead( & tmp) ;
consumerProcess( & tmp) ;
consumerPrinting( i, tmp, 2 ) ;
if ( buffer == 0 ) {
for ( int j = 0 ; j < number; ++ j) {
sem_post( & fullsem) ;
}
}
sem_post( & consumerSync1) ;
}
}
int main( ) {
pthread_t t[ 4 ] ;
sem_init( & fullsem, 0 , 10 ) ;
sem_init( & emptysem, 0 , 0 ) ;
sem_init( & producerSync, 0 , 0 ) ;
sem_init( & producerSync1, 0 , 1 ) ;
sem_init( & consumerSync, 0 , 1 ) ;
sem_init( & consumerSync1, 0 , 1 ) ;
pthread_create( & t[ 0 ] , NULL, & produce, NULL) ;
pthread_create( & t[ 1 ] , NULL, & produce2, NULL) ;
pthread_create( & t[ 2 ] , NULL, & consume, NULL) ;
pthread_create( & t[ 3 ] , NULL, & consume2, NULL) ;
pthread_join( t[ 0 ] , NULL) ;
pthread_join( t[ 1 ] , NULL) ;
pthread_join( t[ 2 ] , NULL) ;
pthread_join( t[ 3 ] , NULL) ;
sem_destroy( & fullsem) ;
sem_destroy( & emptysem) ;
sem_destroy( & consumerSync) ;
sem_destroy( & consumerSync1) ;
sem_destroy( & producerSync) ;
sem_destroy( & producerSync1) ;
return 0 ;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxwdGhyZWFkLmg+CiNpbmNsdWRlIDxzZW1hcGhvcmUuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8bWF0aC5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgoKY2hhciBxdWV1ZU9mQ2hhcnNbMTBdOwppbnQgbnVtYmVyID0gNSwgYnVmZmVyID0gMDsKc2VtX3QgZnVsbHNlbSwgZW1wdHlzZW0sIHByb2R1Y2VyU3luYywgcHJvZHVjZXJTeW5jMSwgY29uc3VtZXJTeW5jLCBjb25zdW1lclN5bmMxOwoKdm9pZCBwcm9kdWNlclByaW50aW5nKGludCBpLCBjaGFyIHRtcCwgaW50IHApIHsKICAgIHByaW50ZigiXG5Qcm9kdWNlciMlZCBhdCBpPSVkIDogSW5zZXJ0ZWQgJWMgLCBidWZmZXI6ICVkIiwgcCwgaSwgdG1wLCBidWZmZXIpOwp9CgpjaGFyIGdlbmVyYXRlQ2hhcigpIHsKICAgIHNsZWVwKDEpOwogICAgc3JhbmQodGltZShOVUxMKSk7CiAgICByZXR1cm4gJ2EnICsgKChyYW5kKCkgKiAxMDApICUgMjYpOwp9Cgp2b2lkIGNvbnN1bWVyUHJvY2VzcyhjaGFyICp0bXApIHsgKnRtcCA9IHRvdXBwZXIoKnRtcCk7IH0KCnZvaWQgY29uc3VtZXJQcmludGluZyhpbnQgaSwgY2hhciB0bXAsIGludCBjKSB7CiAgICBwcmludGYoIlxuQ29uc3VtZXIjJWQgYXQgaT0lZDogR2V0dGluZyAlYywgYnVmZmVyOiVkIiwgYywgaSwgdG1wLCBidWZmZXIpOwp9Cgp2b2lkIGNvbnN1bWVyUmVhZChjaGFyICp0bXApIHsgKnRtcCA9IHF1ZXVlT2ZDaGFyc1stLWJ1ZmZlcl07IH0KCnZvaWQgaW5zZXJ0KGNoYXIgZSkgewogICAgaWYgKGJ1ZmZlciA8IG51bWJlcikKICAgICAgICBxdWV1ZU9mQ2hhcnNbYnVmZmVyKytdID0gZTsKICAgIGVsc2UKICAgICAgICBidWZmZXIgPSAwOwp9CgoKdm9pZCAqcHJvZHVjZSh2b2lkICphKSB7CiAgICBpbnQgaTsKICAgIGZvciAoaSA9IDA7IGkgPCBudW1iZXIgKiAyOyBpKyspIHsKICAgICAgICBzZW1fd2FpdCgmZnVsbHNlbSk7CiAgICAgICAgc2VtX3dhaXQoJnByb2R1Y2VyU3luYzEpOwoKICAgICAgICBjaGFyIHRtcCA9IGdlbmVyYXRlQ2hhcigpOwogICAgICAgIGluc2VydCh0bXApOwogICAgICAgIHByb2R1Y2VyUHJpbnRpbmcoaSwgdG1wLCAxKTsKICAgICAgICBpZiAoYnVmZmVyID4gbnVtYmVyIC0gMSkgewogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IG51bWJlcjsgKytqKSB7CiAgICAgICAgICAgICAgICBzZW1fcG9zdCgmZW1wdHlzZW0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBzZW1fcG9zdCgmcHJvZHVjZXJTeW5jKTsKICAgIH0KfQoKCnZvaWQgKnByb2R1Y2UyKHZvaWQgKmEpIHsKICAgIGludCBpOwogICAgZm9yIChpID0gMDsgaSA8IG51bWJlciAqIDI7IGkrKykgewogICAgICAgIHNlbV93YWl0KCZmdWxsc2VtKTsKICAgICAgICBzZW1fd2FpdCgmcHJvZHVjZXJTeW5jKTsKICAgICAgICBjaGFyIHRtcCA9IGdlbmVyYXRlQ2hhcigpOwogICAgICAgIGluc2VydCh0bXApOwogICAgICAgIHByb2R1Y2VyUHJpbnRpbmcoaSwgdG1wLCAyKTsKICAgICAgICBpZiAoYnVmZmVyID4gbnVtYmVyIC0gMSkgewogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IG51bWJlcjsgKytqKSB7CiAgICAgICAgICAgICAgICBzZW1fcG9zdCgmZW1wdHlzZW0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBzZW1fcG9zdCgmcHJvZHVjZXJTeW5jMSk7CgogICAgfQp9Cgp2b2lkICpjb25zdW1lKHZvaWQgKmEpIHsKICAgIGludCBpOwogICAgZm9yIChpID0gMDsgaSA8IG51bWJlciAqIDI7IGkrKykgewogICAgICAgIHNlbV93YWl0KCZlbXB0eXNlbSk7CiAgICAgICAgc2VtX3dhaXQoJmNvbnN1bWVyU3luYzEpOwogICAgICAgIGNoYXIgdG1wOwogICAgICAgIGNvbnN1bWVyUmVhZCgmdG1wKTsKICAgICAgICBjb25zdW1lclByb2Nlc3MoJnRtcCk7CiAgICAgICAgY29uc3VtZXJQcmludGluZyhpLCB0bXAsIDEpOwogICAgICAgIGlmIChidWZmZXIgPT0gMCkgewogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IG51bWJlcjsgKytqKSB7CiAgICAgICAgICAgICAgICBzZW1fcG9zdCgmZnVsbHNlbSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2VtX3Bvc3QoJmNvbnN1bWVyU3luYyk7CiAgICB9CgoKfQoKCnZvaWQgKmNvbnN1bWUyKHZvaWQgKmEpIHsKICAgIGludCBpLCB2OwogICAgZm9yIChpID0gMDsgaSA8IG51bWJlciAqIDI7IGkrKykgewogICAgICAgIHNlbV93YWl0KCZlbXB0eXNlbSk7CiAgICAgICAgc2VtX3dhaXQoJmNvbnN1bWVyU3luYyk7CgogICAgICAgIGNoYXIgdG1wOwogICAgICAgIGNvbnN1bWVyUmVhZCgmdG1wKTsKICAgICAgICBjb25zdW1lclByb2Nlc3MoJnRtcCk7CiAgICAgICAgY29uc3VtZXJQcmludGluZyhpLCB0bXAsIDIpOwogICAgICAgIGlmIChidWZmZXIgPT0gMCkgewogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IG51bWJlcjsgKytqKSB7CiAgICAgICAgICAgICAgICBzZW1fcG9zdCgmZnVsbHNlbSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2VtX3Bvc3QoJmNvbnN1bWVyU3luYzEpOwoKICAgIH0KCgp9CgppbnQgbWFpbigpIHsKICAgIHB0aHJlYWRfdCB0WzRdOwogICAgc2VtX2luaXQoJmZ1bGxzZW0sIDAsIDEwKTsKICAgIHNlbV9pbml0KCZlbXB0eXNlbSwgMCwgMCk7CiAgICBzZW1faW5pdCgmcHJvZHVjZXJTeW5jLCAwLCAwKTsKICAgIHNlbV9pbml0KCZwcm9kdWNlclN5bmMxLCAwLCAxKTsKICAgIHNlbV9pbml0KCZjb25zdW1lclN5bmMsIDAsIDEpOwogICAgc2VtX2luaXQoJmNvbnN1bWVyU3luYzEsIDAsIDEpOwoKICAgIHB0aHJlYWRfY3JlYXRlKCZ0WzBdLCBOVUxMLCAmcHJvZHVjZSwgTlVMTCk7CiAgICBwdGhyZWFkX2NyZWF0ZSgmdFsxXSwgTlVMTCwgJnByb2R1Y2UyLCBOVUxMKTsKCiAgICBwdGhyZWFkX2NyZWF0ZSgmdFsyXSwgTlVMTCwgJmNvbnN1bWUsIE5VTEwpOwoKCiAgICBwdGhyZWFkX2NyZWF0ZSgmdFszXSwgTlVMTCwgJmNvbnN1bWUyLCBOVUxMKTsKCiAgICBwdGhyZWFkX2pvaW4odFswXSwgTlVMTCk7CiAgICBwdGhyZWFkX2pvaW4odFsxXSwgTlVMTCk7CiAgICBwdGhyZWFkX2pvaW4odFsyXSwgTlVMTCk7CiAgICBwdGhyZWFkX2pvaW4odFszXSwgTlVMTCk7CiAgICBzZW1fZGVzdHJveSgmZnVsbHNlbSk7CiAgICBzZW1fZGVzdHJveSgmZW1wdHlzZW0pOwogICAgc2VtX2Rlc3Ryb3koJmNvbnN1bWVyU3luYyk7CiAgICBzZW1fZGVzdHJveSgmY29uc3VtZXJTeW5jMSk7CiAgICBzZW1fZGVzdHJveSgmcHJvZHVjZXJTeW5jKTsKICAgIHNlbV9kZXN0cm95KCZwcm9kdWNlclN5bmMxKTsKCgogICAgcmV0dXJuIDA7Cn0K
stdout
Producer#1 at i=0 : Inserted g , buffer: 1
Producer#2 at i=0 : Inserted u , buffer: 2
Producer#1 at i=1 : Inserted w , buffer: 3
Producer#2 at i=1 : Inserted g , buffer: 4
Producer#1 at i=2 : Inserted a , buffer: 5
Consumer#2 at i=0: Getting A, buffer:4
Consumer#1 at i=0: Getting G, buffer:3
Consumer#1 at i=1: Getting W, buffer:2
Consumer#2 at i=1: Getting U, buffer:1
Consumer#1 at i=2: Getting G, buffer:0
Producer#2 at i=2 : Inserted k , buffer: 1
Producer#1 at i=3 : Inserted m , buffer: 2
Producer#2 at i=3 : Inserted g , buffer: 3
Producer#1 at i=4 : Inserted a , buffer: 4
Producer#2 at i=4 : Inserted M , buffer: 5
Consumer#2 at i=2: Getting M, buffer:4
Consumer#2 at i=3: Getting A, buffer:3
Consumer#1 at i=3: Getting G, buffer:2
Consumer#1 at i=4: Getting M, buffer:1
Consumer#2 at i=4: Getting K, buffer:0
Producer#1 at i=5 : Inserted Q , buffer: 1
Producer#2 at i=5 : Inserted [ , buffer: 2
Producer#1 at i=6 : Inserted U , buffer: 3
Producer#2 at i=6 : Inserted y , buffer: 4
Producer#1 at i=7 : Inserted O , buffer: 5
Consumer#1 at i=5: Getting O, buffer:4
Consumer#2 at i=5: Getting Y, buffer:3
Consumer#2 at i=6: Getting U, buffer:2
Consumer#1 at i=6: Getting [, buffer:1
Consumer#2 at i=7: Getting Q, buffer:0
Producer#2 at i=7 : Inserted o , buffer: 1
Producer#1 at i=8 : Inserted Q , buffer: 2
Producer#2 at i=8 : Inserted m , buffer: 3
Producer#1 at i=9 : Inserted a , buffer: 4
Producer#2 at i=9 : Inserted o , buffer: 5
Consumer#1 at i=7: Getting O, buffer:4
Consumer#1 at i=8: Getting A, buffer:3
Consumer#2 at i=8: Getting M, buffer:2
Consumer#2 at i=9: Getting Q, buffer:1
Consumer#1 at i=9: Getting O, buffer:0