美文网首页
生产者消费者问题(Linux)

生产者消费者问题(Linux)

作者: SummerC0ld | 来源:发表于2017-04-06 15:27 被阅读0次

C实现

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define NEED_P 2
#define NEED_C 3
#define WORKS_P 6
#define WORKS_C 4
#define BUF_LENGTH (sizeof(struct mybuffer))
#define LETTER_NUM 3
#define SHM_MODE 0600
#define SEM_ALL_KEY 1234
#define SEM_EMPTY 0
#define SEM_FULL 1
//缓冲区结构(循环队列)
struct mybuffer
{
      char letter[LETTER_NUM];
      int head;
      int tail;
      int is_empty;
};
//得到5以内的一个随机数
int get_random()
{
      int t;
      srand((unsigned)(getpid() + time(NULL)));
      t = rand() % 5;
      return t;
}
//得到A~Z的一个随机字母
char get_letter()
{
      char a;
      srand((unsigned)(getpid() + time(NULL)));
      a = (char)((char)(rand() % 26) + 'A');
      return a;
}
//P操作
void p(int sem_id, int sem_num)
{
      struct sembuf xx;
      xx.sem_num = sem_num;
      xx.sem_op = - 1;
      xx.sem_flg = 0;
      semop(sem_id, & xx, 1);
}
//V操作
void v(int sem_id, int sem_num)
{
      struct sembuf xx;
      xx.sem_num = sem_num;
      xx.sem_op = 1;
      xx.sem_flg = 0;
      semop(sem_id, & xx, 1);
}
//主函数
int main(int argc, char *argv[])
{
      int i, j;
      int shm_id, sem_id;
      int num_p = 0, num_c = 0;
      struct mybuffer *shmptr;
      char lt;
      time_t now;
      pid_t pid_p, pid_c;
      
    sem_id = semget(SEM_ALL_KEY, 2, IPC_CREAT | 0660);
      if (sem_id >= 0)
    
  {
            printf("主进程开始,信号量创建完毕\n");
        
  }
      semctl(sem_id, SEM_EMPTY, SETVAL, LETTER_NUM);
      semctl(sem_id, SEM_FULL, SETVAL, 0);
      
    if ((shm_id = shmget(IPC_PRIVATE, BUF_LENGTH, SHM_MODE)) < 0)
    
  {
            printf("Error on shmget.\n");
            exit(1);
        
  }
      if ((shmptr = shmat(shm_id, 0, 0)) == (void *)-1)
    
  {
            printf("Error on shmat.\n");
            exit(1);
        
  }
      shmptr->head = 0;
      shmptr->tail = 0;
      shmptr->is_empty = 1;
      
    while ((num_p++) < NEED_P)
    
  {
            if ((pid_p = fork()) < 0)
        
    {
                  printf("Error on fork.\n");
                  exit(1);
              
    }
             //如果是子进程,开始创建生产者
        if (pid_p == 0)
        
    {
                  if ((shmptr = shmat(shm_id, 0, 0)) == (void *)-1)
            
      {
                        printf("Error on shmat.\n");
                        exit(1);
                    
      }
                  for (i = 0; i < WORKS_P; i++)
            
      {
                        p(sem_id, SEM_EMPTY);
                        sleep(get_random());
                        shmptr->letter[shmptr->tail] = lt = get_letter();
                        shmptr->tail = (shmptr->tail + 1) % LETTER_NUM;
                        shmptr->is_empty = 0;
                        now = time(NULL);
                        printf("当前时间 %02d:%02d:%02d\t", localtime(&now)->tm_hour, localtime(&now)->tm_min, localtime(&now)->tm_sec);
            printf("生产者 %d 放入 '%c'\t当前缓冲区:", num_p, lt);
                        for (j = (shmptr->tail - 1 >= shmptr->head) ? (shmptr->tail - 1) : (shmptr->tail - 1 + LETTER_NUM); !(shmptr->is_empty) && j >= shmptr->head; j--)
                
        {
                              printf("%c", shmptr->letter[j % LETTER_NUM]);
                          
        }
            printf("\n");
                        fflush(stdout);
                        v(sem_id, SEM_FULL);
                    
      }
                  shmdt(shmptr);
                  exit(0);
              
    }
        
  }
      while (num_c++ < NEED_C)
    
  {
            if ((pid_c = fork()) < 0)
        
    {
                  printf("Error on fork.\n");
                  exit(1);
              
    }
             //如果是子进程,开始创建消费者
        if (pid_c == 0)
        
    {
                  if ((shmptr = shmat(shm_id, 0, 0)) == (void *)-1)
            
      {
                        printf("Error on shmat.\n");
                        exit(1);
                    
      }
                  for (i = 0; i < WORKS_C; i++)
            
      {
                        p(sem_id, SEM_FULL);
                        sleep(get_random());
                        lt = shmptr->letter[shmptr->head];
                        shmptr->head = (shmptr->head + 1) % LETTER_NUM;
                        shmptr->is_empty = (shmptr->head == shmptr->tail);
                        now = time(NULL);
                        printf("当前时间 %02d:%02d:%02d\t", localtime(&now)->tm_hour, localtime(&now)->tm_min, localtime(&now)->tm_sec);
             printf("消费者 %d 拿走 '%c'\t当前缓冲区:", num_c, lt);
                        for (j = (shmptr->tail - 1 >= shmptr->head) ? (shmptr->tail - 1) : (shmptr->tail - 1 + LETTER_NUM); !(shmptr->is_empty) && j >= shmptr->head; j--)
                
        {
                              printf("%c", shmptr->letter[j % LETTER_NUM]);
                          
        }
                        printf("\n");
                        fflush(stdout);
                        v(sem_id, SEM_EMPTY);
                    
      }
                  shmdt(shmptr);
                  exit(0);
              
    }
        
  }
      
     //主控程序最后退出
    while (wait(0) != - 1);
      shmdt(shmptr);
      shmctl(shm_id, IPC_RMID, 0);
      semctl(sem_id, IPC_RMID, 0);
      printf("主程序完成\n");
      fflush(stdout);
      exit(0);
}

相关文章

  • 生产者和消费者问题

    生产者和消费者问题 问题简述 组成 系统中有一组生产者和消费者进程 生产者生产者将产品放入缓冲区 消费者消费者进程...

  • 操作系统知识点持续更新

    生产者消费者问题 关于生产者消费者问题可以参考这篇文章:生产者消费者问题的java实现 临界区与互斥量 临界区:保...

  • 经典同步互斥问题

    生产者消费者问题 生产者消费者应当是最最基本的同步互斥问题了。生产者生产了之后消费者才消费,消费者消费之后,通知生...

  • 生产者和消费者问题详解

    生产者和消费者问题详解 定义 生产者消费者问题(英语:Producer-consumer problem),也称有...

  • 2-1.死锁-经典同步问题

    三、经典同步问题 1.生产者-消费者问题 计算机系统中的许多问题都可归结为生产者与消费者问题,生产者与消费者可以通...

  • 9. python多进程之Queue实现生产者消费者模型

    一、概述 什么是生产者消费者模式生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此...

  • 生产者消费者

    什么是生产者和消费者 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。 生产者和消费者彼此之间不直...

  • java生产者消费者实现

    什么是生产者消费者模式 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直...

  • 生产者消费者模式-java原生、Disruptor实现方案

    生产者消费者模式介绍 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接...

  • Java实现生产者-消费者模型的几种方法

    什么是生产者消费者模式 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直...

网友评论

      本文标题:生产者消费者问题(Linux)

      本文链接:https://www.haomeiwen.com/subject/ttdqattx.html