Semaphore Consumer-Producer Code

#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);
}

你可能感兴趣的:(semaphore,c,信号量,生产者-消费者)