Linux下生产者消费者问题

2023-05-16

Linux下生产者消费者问题

题目:

  • 5个生产者
  • 4个消费者
  • 3缓冲区
  • 总共15个产品,这15个产品被消耗以后生产者消费者线程都结束

要求

  • 每个产品的数据结构:至少包含产品编号、生产者编号、生产时间、缓冲区中存储编号、消费者编号;
  • 生产和消费都需要随机时间(1~5s);
  • 不能产生竞态、不能死锁
  • 对公共缓冲区的操作:操作前、操作后要显示公共缓冲区中各个产品项的状态

解题思路

1.使用信号量对缓冲区里的数据进行同步;
(1)声明信号量

sem_t room_sem; //缓冲区现存空闲空间 
sem_t product_sem; //缓冲区现在所有产品数量

(2)初始化信号量

int ret = sem_init(&room_sem, 0, POOL_SIZE-1);
    ret = sem_init(&product_sem, 0, 0);

(3)关于信号量的使用可以参照博客

2.使用互斥量对临界区代码进行保护;

pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);

3.使用结构体存储产品信息;

struct Product{   
    int p_id;    
    long pcer_id;   
    struct tm *p_time;   //时间
    int cache_number;  
    long c_id;
};

4.使用rand函数产生随机时间;

      int x = rand()%5 //随机得到数0,1,2,3,4

下面是完整代码

#include<stdio.h>
#include<time.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<semaphore.h>
#define P_NUMBER 5 //the number of producer
#define C_NUMBER 4 //the number of consumer
#define POOL_SIZE 3 //the number of cache
int c_p = 0; //consume product
int p_p = 0; //produce product
sem_t room_sem; // synchronizing signal ,being used to reflect that there remains available room
sem_t product_sem; //synchronizing signal, being used to reflect that there exisits capable product
pthread_mutex_t mutex; //mutually exclusive lock
int count = 0;

struct tm *gettime(){ //acquire current time
    time_t ptime;
    struct tm *p;
    time(&ptime);
    p = gmtime(&ptime);
    return p;
}
struct Product{
    int p_id;
    long pcer_id;
    struct tm *p_time;
    int cache_number;
    long c_id;
} producer [POOL_SIZE];//the message of products

void *producer_fun(void *args){
    printf("this is producer %ld thread\n",(long) args);
    while (1)
    {
        usleep((rand()%5+1)*1000);
        sem_wait(&room_sem);
        pthread_mutex_lock(&mutex);
        //producer starts to produce product
        if(count == 15){
            exit(1);
        }
        printf("*******************************There is no pre-operation state***************************************************\n");
        printf("   product_id       producer_id       product_time      POOL_id        consumer_id\n");
        for(int i = 0; i < 3;i++){
            printf("%d    %d               %ld                %d:%d:%d          %d               %ld\n",
            i,
            producer[i].p_id,
            producer[i].pcer_id,
            producer[i].p_time->tm_hour, producer[i].p_time->tm_min,producer[i].p_time->tm_sec,
            producer[i].cache_number,
            producer[i].c_id);
        }
        printf("*****************************************************************************************************************\n");
        producer[p_p].cache_number = p_p;
        producer[p_p].c_id = -1;
        producer[p_p].p_id = count;
        producer[p_p].p_time = gettime();
        producer[p_p].pcer_id = (long)args;
        count++;
        printf("product %d is produced by producer %ld\n", producer[p_p].p_id, producer[p_p].pcer_id);
        printf("*******************************There is the state after the operation********************************************\n");
        printf("   product_id       producer_id       product_time      POOL_id        consumer_id\n");
        for(int i = 0; i < 3;i++){
            printf("%d    %d               %ld                %d:%d:%d           %d               %ld\n",
            i,
            producer[i].p_id,
            producer[i].pcer_id,
            producer[i].p_time->tm_hour, producer[i].p_time->tm_min,producer[i].p_time->tm_sec,
            producer[i].cache_number,
            producer[i].c_id);
        }
        printf("****************************************************************************************************************\n\n\n");
        p_p = (p_p + 1)%POOL_SIZE;
        pthread_mutex_unlock(&mutex);
        sem_post(&product_sem);
    }
}

void *consumer_fun(void *args){
    printf("this is consumer %ld thread\n", (long) args);
    while(1){
        usleep((rand()%5+1)*1000);
        sem_wait(&product_sem);
        pthread_mutex_lock(&mutex);
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~There is no pre-operation state~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        printf("   product_id       producer_id       product_time      POOL_id        consumer_id\n");
        for(int i = 0; i < 3;i++){
            printf("%d    %d               %ld                %d:%d:%d          %d               %ld\n",
            i,
            producer[i].p_id,
            producer[i].pcer_id,
            producer[i].p_time->tm_hour, producer[i].p_time->tm_min,producer[i].p_time->tm_sec,
            producer[i].cache_number,
            producer[i].c_id);
        }
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        producer[c_p].c_id = (long)args;
        printf("product %d was customed by customer %ld\n", producer[c_p].p_id, producer[c_p].c_id);
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~There is the state after the operation~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
        printf("   product_id       producer_id       product_time      POOL_id        consumer_id\n");
        for(int i = 0; i < 3;i++){
            printf("%d    %d               %ld                %d:%d:%d          %d               %ld\n",
            i,
            producer[i].p_id,
            producer[i].pcer_id,
            producer[i].p_time->tm_hour, producer[i].p_time->tm_min,producer[i].p_time->tm_sec,
            producer[i].cache_number,
            producer[i].c_id);
        }
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\n");
        c_p = (c_p + 1)%POOL_SIZE;
        pthread_mutex_unlock(&mutex);
        sem_post(&room_sem);
    }
}

int main()
{
    pthread_t producer_id[P_NUMBER];
    pthread_t consumer_id[C_NUMBER];
    pthread_mutex_init(&mutex, NULL);
    for(int i=0; i<POOL_SIZE;i++){
        producer[i].pcer_id = -1;
        producer[i].p_id = -1;
        producer[i].cache_number = -1;
        producer[i].c_id = -1;
        producer[i].p_time = gettime();
    }
    int ret = sem_init(&room_sem, 0, POOL_SIZE-1);
    if(ret != 0){
        printf("sem_int error \n");
        exit(1);
    }
    ret = sem_init(&product_sem, 0, 0);
    if(ret != 0){
        printf("sem_int error!\n");
        exit(1);
    }
    for(long i = 0; i<P_NUMBER;i++){
        ret = pthread_create(&producer_id[i], NULL, producer_fun, (void*)i);
        if(ret != 0){
            printf("creating producer_id errors!\n ");
            exit(1);
        }
    }
    for(long i = 0; i<C_NUMBER; i++){
        ret = pthread_create(&consumer_id[i], NULL, consumer_fun, (void*)i);
        if(ret != 0){
            printf("creating consumer errors!\n");
            exit(1);
        }
    }
    for(int i=0;i<C_NUMBER;i++){
        pthread_join(producer_id[i], NULL);
        pthread_join(consumer_id[i], NULL);
   }
   pthread_join(producer_id[4], NULL);
   return 0;
}

下面是结果

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux下生产者消费者问题 的相关文章

  • 我们如何在使用循环时调用 ansible playbook 中的变量

    我有两个文件 其中这些文件包含server names and server IP s 我想更改 替换一些特定的server names and IP addressees根据要求在两个文件中 这与这篇文章 因为它被要求开设一个新职位 ht
  • 如何通过 makefile 在 Linux 上安装程序? [复制]

    这个问题在这里已经有答案了 可能的重复 Linux Unix make install 应该包含什么 https stackoverflow com questions 528399 what should linux unix make
  • 我想在 Red Hat Linux 服务器中执行 .ps1 powershell 脚本

    我有一个在窗口中执行的 ps1 powershell 脚本 但我的整个数据都在 Linux 服务器中 有什么可能的方法可以让我在红帽服务器中执行 powershell 脚本 powershell脚本是 Clear Host path D D
  • Linux 内核使用的设备树文件 (dtb) 可视化工具? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个可以图形化表示Linux内核中使用的硬件设备树的工具 我正在尝试了解特定 Arm 芯片组
  • 使用 shell 脚本发送 HTML 邮件

    如何使用 shell 脚本发送 HTML 电子邮件 首先 您需要撰写消息 最低限度由这两个标头组成 MIME Version 1 0 Content Type text html 以及适当的消息正文 p Hello world p 获得后
  • Vagrant 遇到问题 - “404 - 未找到”

    我正在尝试使用 Vagrant 制作一个 LAMP 盒子 有人告诉我它使用起来非常简单 我对网络和虚拟机完全陌生 对 Linux Ubuntu 的经验也很少 我目前已尝试按照官方文档页面上的教程进行操作 http docs vagrantu
  • 在 Linux 中重新启动时,新创建的文件变为 0 kb(数据被覆盖为空)

    我遇到了一个奇怪的问题 这让我发疯 当前的任务是在 root 用户第一次登录时启动一组文件 并在同一用户第二次登录时启动另一组文件 我决定使用 profile 和 bashrc 文件 并在第一次登录期间发生的任务结束时重新加载 bashrc
  • 为什么此 NASM 代码会打印我的环境变量?

    本学期我刚刚完成计算机体系结构课程 除其他外 我们一直在涉足 MIPS 汇编并在 MARS 模拟器中运行它 今天 出于好奇 我开始在我的 Ubuntu 机器上摆弄 NASM 基本上只是将教程中的内容拼凑起来 并感受一下 NASM 与 MIP
  • Linux shell 从用户输入中获取设备 ID

    我正在为一个程序编写安装脚本 该程序需要在其配置中使用 lsusb 的设备 ID 因此我正在考虑执行以下操作 usblist lsusb put the list into a array for each line use the arr
  • 在 x86 汇编语言中获取文件大小的简单方法

    假设我已经在汇编中打开了一个文件 并且在寄存器 eax 中有该文件的文件句柄 我将如何获取文件的大小 以便为其分配足够的缓冲区空间 我在这里研究了另一个讨论 建议使用sys fstat 28 系统调用来获取文件统计信息但无法实现它 My a
  • 嵌入清单文件以要求具有 mingw32 的管理员执行级别

    我正在 ubuntu 下使用 i586 mingw32msvc 交叉编译应用程序 我很难理解如何嵌入清单文件以要求 mingw32 具有管理员执行级别 对于我的例子 我使用了这个hello c int main return 0 这个资源文
  • 如何从 C++ 程序中重新启动 Linux?

    我有一个 Qt 4 GUI 我需要在下拉菜单中提供一个选项 允许用户选择重新启动计算机 我意识到这对于以其他方式重新启动计算机的能力来说似乎是多余的 但选择需要保留在那里 我尝试使用 system 来调用以下内容 suid root she
  • 如何在线程创建和退出时调用函数?

    include
  • grep 排除文件的数组参数

    我想从我的文件中排除一些文件grep命令 为此我使用参数 exclude excluded file ext 为了更容易阅读 我想使用包含排除文件的 bash 数组 EXCLUDED FILES excluded file ext 然后将
  • ioctl 命令的用户权限检查

    我正在实现 char 驱动程序 Linux 并且我的驱动程序中有某些 IOCTL 命令仅需要由 ADMIN 执行 我的问题是如何在 ioctl 命令实现下检查用户权限并限制非特权用户访问 IOCTL 您可以使用bool capable in
  • 批量删除文件名中包含 BASH 中特殊字符的子字符串

    我的目录中有一个文件列表 opencv calib3d so2410 so opencv contrib so2410 so opencv core so2410 so opencv features2d so2410 so opencv
  • 仅使用containerd(不使用Docker)修剪容器镜像

    如果我刚刚containerd安装在 Linux 系统上 即 Docker 是not安装 如何删除未使用的容器映像以节省磁盘空间 Docker 就是这么方便docker system prune https docs docker com
  • 如何使用 JSch 将多行命令输出存储到变量中

    所以 我有一段很好的代码 我很难理解 它允许我向我的服务器发送命令 并获得一行响应 该代码有效 但我想从服务器返回多行 主要类是 JSch jSch new JSch MyUserInfo ui new MyUserInfo String
  • linux下无法创建僵尸进程

    嗯 我有一个奇怪的问题 我无法在我的项目中创建僵尸进程 但我可以在其他文件中创建僵尸进程 有简单的说明 int main if fork 0 printf Some instructions n else sleep 10 wait 0 r
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe

随机推荐