Skip to content

Instantly share code, notes, and snippets.

@jaseemabid
Created February 27, 2012 08:54
Show Gist options
  • Save jaseemabid/1922623 to your computer and use it in GitHub Desktop.
Save jaseemabid/1922623 to your computer and use it in GitHub Desktop.
PRODUCER - CONSUMER Implementation in C
/** PRODUCER - CONSUMER PROBLEM **/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <pthread.h>
#include <stdlib.h>
#define BUFSIZE 10
#define MUTEX 0
#define FULL 1
#define EMPTY 2
int semid;
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */
};
int sem_create(int nsems) {
int id;
key_t key = 1234;
int semflg = IPC_CREAT | 0666;
id = semget(key, nsems, semflg);
if(id < 0)
{
perror("semget:");
exit (1);
}
return id;
}
void sem_initialise(int semno, int val) {
union semun un;
un.val = val;
if(semctl(semid, semno, SETVAL, un) < 0)
{
// printf("%d\n", semno);
perror("semctl:");
exit(2);
}
}
void *producer(void *id);
void *consumer(void *id);
void wait(int semno);
void signal(int semno);
int buffer[BUFSIZE], data;
int in = 0;
int out = 0;
int i = 10000;
int j = 10000;
int main (int argc, char *argv[]) {
semid = sem_create(3);
sem_initialise(MUTEX, 1);
sem_initialise(FULL, 0);
sem_initialise(EMPTY, 10);
pthread_t prod, cons;
pthread_create(&prod, NULL, producer, (void *)semid);
pthread_create(&cons, NULL, consumer, (void *)semid);
pthread_exit(NULL);
return 0;
}
void *producer(void *id) {
int semid = (int) id;
data = 0;
while(i--) {
wait(EMPTY);
wait(MUTEX);
/** Critical Section **/
buffer[in] = data;
in = (in + 1) % BUFSIZE;
data = (data + 1) % BUFSIZE;
printf("P:%d\n", data);
//printf("P\n");
signal(MUTEX);
signal(FULL);
}
pthread_exit(NULL);
}
void *consumer(void *id) {
int semid = (int) id;
while(j--)
{
wait(FULL);
wait(MUTEX);
/** Critical Section **/
data = buffer[out];
out = (out + 1) % BUFSIZE;
printf("C:%d\n", data);
/** **/
signal(MUTEX);
signal(EMPTY);
}
pthread_exit(NULL);
}
void wait(int semno) {
struct sembuf buf;
buf.sem_num = semno;
buf.sem_op = -1;
buf.sem_flg = 0;
if(semop(semid, &buf, 1) < 0) {
perror("semop:");
exit(2);
}
}
void signal(int semno) {
struct sembuf buf;
buf.sem_num = semno;
buf.sem_op = 1;
buf.sem_flg = 0;
if(semop(semid, &buf, 1) < 0)
{
perror("semop:");
exit(2);
}
}
@jaseemabid
Copy link
Author

Execute : gcc foo.c -lpthread && ./a.out

@dassdmc
Copy link

dassdmc commented May 16, 2018

why do we execute it as gcc foo.c -lpthread

@matheustavares
Copy link

why do we execute it as gcc foo.c -lpthread

You compile with gcc foo.c which generates the binary a.out (the -lpthread is to tell gcc to link it against the pthreads lib). Then, if the compiling command works (i.e. "&&"), ./a.out is executed, which is the generated binary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment