You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++实现生产者消费者模式时生产者连续打印3次异常排查

生产者消费者进程通信连续发送异常分析与修复

异常原因

  • 信号量创建参数错误:代码中sem_id = semget(IPC_PRIVATE, m, 0600);第二个参数传入的是生产者数量m,但实际使用了3个信号量(互斥锁PISI、空槽位PUN、满槽位PRAZAN),如果生产者数量小于3,会导致信号量访问越界,信号量控制逻辑完全失效。
  • 临界区内放置sleep阻塞逻辑:生产者拿到互斥锁PISI完成数据写入后,在临界区内执行sleep(1),占用锁的期间其他进程无法操作缓冲区,释放锁后如果当前生产者再次抢到锁,就会出现连续发送的情况。
  • 消费者消费逻辑延迟:消费者在申请满槽位信号量PRAZAN前先执行sleep(1),导致消费速度远慢于生产速度,长度为5的缓冲区很快被生产者填满,自然会出现多个连续的生产者发送日志。
  • 总数据量计算错误:main函数中初始化完共享内存后执行了m++(用于适配fork消费者+生产者的总进程数),但消费者循环判断条件i < n*m用了自增后的m,导致消费者预期接收的总数据量比实际多,同时子进程执行完业务逻辑后没有主动退出,会产生多余进程干扰正常输出。

修复方案

  1. 修正信号量创建参数:将semget的第二个参数固定为3,保证3个信号量都能正常初始化:
sem_id = semget(IPC_PRIVATE, 3, 0600);
  1. 调整sleep的位置到临界区外:生产者释放完所有信号量后再执行sleep,消费者申请信号量前不要sleep,消费完成释放信号量后再sleep,保证生产消费速度匹配。
    修改后生产者核心逻辑:
do
{
    ispitaj(PUN);
    ispitaj(PISI);
    medo->meduspremnik[medo->ULAZ] = rand() % 1000;
    cout << "Proizvodac " << neka << " salje: " << "''" << medo->meduspremnik[medo->ULAZ] << "''" << endl;
    medo->ULAZ = (medo->ULAZ + 1) % 5;
    postavi(PISI);
    postavi(PRAZAN);
    sleep(1); // sleep移到临界区外
    i = i + 1;
}while(i < n);

修改后消费者核心逻辑:

do
{
    ispitaj(PRAZAN); // 去掉开头的sleep,直接申请信号量
    cout << "Potrosac prima " << medo->meduspremnik[medo->IZLAZ] << "." << endl;
    zbroj += medo->meduspremnik[medo->IZLAZ];
    medo->IZLAZ = (medo->IZLAZ+1) % 5;
    postavi(PUN);
    sleep(1); // 消费完成后再加sleep
    i = i+1;
}while (i < n * m);
  1. 单独存储总进程数,不要修改原始生产者数量m,同时子进程执行完逻辑后主动退出:
int m = atoi(argv[1]); // 原始生产者数量,后续不再修改
int n = atoi(argv[2]);
int process_cnt = m + 1; // 总进程数=生产者数+1个消费者
// 省略共享内存、信号量初始化逻辑
for(int i = 0; i < process_cnt; i++)
{
    switch(fork())
    {
        case 0:
            if(i == 0)
            {
                potrosac();
            }
            else
            {
                proizvodac(i);
            }
            exit(0); // 子进程执行完直接退出,避免执行后续逻辑
        case -1:
            perror("fork error");
            exit(1);
    }
}

内容的提问来源于stack exchange,提问作者Exch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 22:24:04