编程模拟生产者-消费者模型的进程控制(互斥与同步)

编程模拟生产者-消费者模型的进程控制(互斥与同步)

1.1、设计目的

  1. 加深对进程概念的理解,明确进程和程序的区别
  2. 进一步认识并发执行的实质
  3. 用信号量的机制实现进程互斥的方法
  4. 用信号量的机制实现进程同步的方法

1.2、开发环境

window10系统的Dev-C++环境
## 如何改变文本的样式

1.3、原理

其中有三种关系:
①生产者与生产者:互斥
②消费者与消费者:互斥
③生产者与消费者:同步互斥

生产者与消费者模型是基于一个场景,就是生产者在每次生产一个数据必须要放在一个仓库中,而消费者消费必须去仓库中拿数据,这样我们就会产生一些问题,比如,在生产者生产好数据去仓库放东西的时候,消费者是不能进去的,同行消费者取的时候,生产者也不能进去。当仓库为空的时候消费者就得等生产者放数据,仓库满了就必须等消费者取数据。所以为了满足上面的需求,我们就用同步与互斥来进行让他们有效的进行。

1.4、数据与程序

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t mutex;  // 互斥量
pthread_cond_t cond;    // 条件
int count = 0;   // 用与记录次数
// 用一个链表来当作仓库
typedef struct ListNode
{
    struct ListNode* next;
    int data;
}ListNode;
ListNode head;  // 带头节点
ListNode* CreateNode(int value)
{
    ListNode* new_node = (ListNode*)malloc(sizeof(ListNode));
    new_node->next = NULL;
    new_node->data = value;
    return new_node;
}
void Init(ListNode* head)
{
    head->data = 0;
    head->next = NULL;
}
void Push(ListNode* head, int value)
{
    if (head == NULL)
    {
        return;
    }
    ListNode* node = CreateNode(value);
    ListNode* nex = head->next;
    head->next = node;
    node->next = nex;
}
void Pop(ListNode* head, int *top)
{
    if (head == NULL)
    {
        return;
    }
    if (head->next == NULL)
    {
        return;
    }
    *top = head->next->data;
    ListNode* node = head->next;
    head->next = node->next;
    free(node);
}
//生产者
void* Producer(void* arg)
{
    (void)arg;
    while (1)
    {
        // 加锁
        pthread_mutex_lock(&mutex);
        Push(&head, count);
        printf("Producer %d \n", head.next->data);
        ++count;
        // 产生一个数据,就要唤醒等待的线程
        pthread_cond_signal(&cond);
        // 解锁
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
    return NULL;
}
//消费者
void* Consumer(void* arg)
{
    (void)arg;
    while (1)
    {
        int value = -1;
        pthread_mutex_lock(&mutex);
        // 这里用while是因为有可能被信号打断,
        // 当再次返回时候,就可以重新判断
        // 也有可能被其它异常信号唤醒
        while (head.next == NULL)
        {
            // 没有数据,就要进行
            // 解锁
            // 等待
            // 加锁
            pthread_cond_wait(&cond, &mutex);
        }
        Pop(&head, &value);
        printf("consumer %d\n",value);

        pthread_mutex_unlock(&mutex);
        usleep(100000);
    }
    return NULL;
}

int main()
{
    Init(&head);
    // 初始化
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
    // 创建线程
    pthread_t producer, consumer;
    pthread_create(&producer, NULL, Producer, NULL);
    pthread_create(&consumer, NULL, Consumer, NULL);
    // 等待线程
    pthread_join(producer, NULL);
    pthread_join(consumer, NULL);
    // 销毁同步与互斥量
    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);
    return 0;
}

1.5、程序运行结果

在这里插入图片描述

1.6实验总结与心得体会

理解了进程概念,明确了进程和程序之间的区别,进一步认识并发执行的实质。

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三毛是she

感谢打赏,我会继续努力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值