#include
#include
#include
#include
#include
#include
#include
#define N 10
#define mutex 0
#define empty 1
#define full 2
int id;
int ID[3];
char str[N + 1];
char cstr[2];
int i = 0;
char c = 'a';
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
int set_semvalue(int sem_id, int type, int value)
{
union semun sem_union;
sem_union.val = value;
if(semctl(sem_id, type, SETVAL, sem_union) == -1)
return 0;
return 1;
}
void del_semvalue()
{
union semun sem_union;
int i = 0;
if(semctl(id, 0, IPC_RMID, sem_union) == -1)
fprintf(stderr, "Failed to delete semaphore\n");
printf("semaphore is deleted\n");
exit(0);
}
int down(int sem_id, int type)
{
struct sembuf sem_b = {type, -1, SEM_UNDO};
if(semop(sem_id, &sem_b, 1) == -1){
fprintf(stderr, "down failed\n");
return 0;
}
// printf("down successfully\n");
return 1;
}
int up(int sem_id, int type)
{
struct sembuf sem_b = {type, 1, SEM_UNDO};
if(semop(sem_id, &sem_b, 1) == -1){
fprintf(stderr, "up failed\n");
return 0;
}
// printf("up successfully\n");
return 1;
}
void consume()
{
printf(" ");
printf(" consumer: %-10s ", str);
strcpy(str, str+1);
printf("--> %-10s\n", str);
fflush(stdout);
}
void produce()
{
if(c > 'z')
c = 'a';
sprintf(cstr, "%c", c++);
printf("producer: %-10s ", str);
strcat(str, cstr);
printf("--> %-10s\n", str);
fflush(stdout);
}
void *consumer(void* arg)
{
while(1){
if(!down(id, full)) exit(1);
if(!down(id, mutex)) exit(1);
consume();
if(!up(id, mutex)) exit(1);
if(!up(id, empty)) exit(1);
}
}
void *producer(void* arg)
{
while(1){
if(!down(id, empty)) exit(1);
if(!down(id, mutex)) exit(1);
produce();
if(!up(id, mutex)) exit(1);
if(!up(id, full)) exit(1);
}
}
int main()
{
// Create semaphore set
id = semget((key_t) 1111, 3, 0666 | IPC_CREAT);
// Set semaphore number to 1 in mutex
if(!set_semvalue(id, mutex, 1)){
fprintf(stderr, "Failed to initilize mutex_semaphore\n");
exit(1);
}
// Set semaphore number to N in empty
if(!set_semvalue(id, empty, N)){
fprintf(stderr, "Failed to initilize empty_semaphore\n");
exit(1);
}
// Set semaphore number to 0 in full
if(!set_semvalue(id, full, 0)){
fprintf(stderr, "Failed to initilize full_semaphore\n");
exit(1);
}
// Delete semaphore when receive SIGINT
signal(SIGINT, del_semvalue);
// initialize str and cstr
memset(str, '\0', N+1);
memset(cstr, '\0', 2);
pthread_t consumer_id;
pthread_t producer_id;
// create threads for consumer and producer
pthread_create(&consumer_id, NULL, consumer, NULL);
pthread_create(&producer_id, NULL, producer, NULL);
pthread_join(consumer_id, NULL);
pthread_join(producer_id, NULL);
exit(0);
}