当前位置: 首页 > news >正文

条件变脸pthread_cond_signal丢失问题

直接上代码:

static bsem_t bsem;
void* t1(void *arg)
{
    /*printf("enter task 1\n");*/
    /*while(1)*/
    /*{*/
        /*sleep(2);*/
        bsem_post(&bsem);
        /*bsem_post_all(&bsem);*/
        /*printf("this is task1, post sem\n");*/

}

void* t2(void *arg)
{
    /*printf("enter task 2\n");*/
    while(1)
    {
        /*usleep(100000);*/
        bsem_wait(&bsem);
        printf("this thread[%u],is wait task2\n", pthread_self());
    }
}

int main()
{
    printf("enter main .... \n");
    int ret = 0;
    bsem_init(&bsem, 0);
    pthread_t thread1[2];
    pthread_t thread2[5];

    int i;
    for(i=0; i< 2; i++)
    {
        ret = pthread_create(&thread2[i], NULL,(void*)t2, NULL);
        if(ret!=0)
        {
             printf("pthread create fail");
        }
    }

    /*sleep(1);*/
    /*for(i=0; i< 2; i++)*/
    /*{*/
        ret = pthread_create(&thread1[0], NULL,(void*)t1, NULL);
        if(ret!=0)
        {
             printf("pthread create fail");
        }
    /*}*/
        /*sleep(1);*/
        ret = pthread_create(&thread1[0], NULL,(void*)t1, NULL);

    while(1);

    return 0;
}

在main函数中会先创建两个wait thread, 然后在创建两个post线程,运行多次会发现pthread_cond_signal丢失的显现,如下图:

可以发现执行post的条件是获取mutex, 这个mutex是所有情况大家都共用的,所以就会存在可能:
wait 和 post都在等待这个mutex, 某些时候wait获取锁不及时,被两个连续的post获取mutex两次,然后执行啦两次signal,但是只出发了一个wait等待。

wait只知道被触发,但是它并不知道是被第几个signal触发的。

在这个条件变量的实现中,V=1的时候才会触发成功,V=0会执行wait动作, 所以当:
V=1, wait, V=0  --> V=1,wait, V=0 这种是我们希望得到的顺序,但是也有上面的那种可能就是:
V=1, V=1, wait, V=0 -> wait,  知道等待新的Post把V置为1,才会继续向下执行。

 

修改如下,解决此问题:

增加count的计数。这个时候这个bsem就像是semphore的功能,但并不是完全是, V的值表示会触发多少个wait等待。

相关文章:

  • 必须掌握的8个dos命令
  • libcurl多线程超时设置不安全
  • 可视化库-Matplotlib-直方图(第四天)
  • 微信支付JSAPI,实测!终极方案
  • 【转载】关于nginx以及内核参数的配置
  • Material Design设计规范在ComponentOne For WinForm的应用(上)
  • 从数据中心基础设施的视角来看 Facebook 机器学习的应用
  • 073:【Django数据库】ORM聚合函数详解-Count
  • 2019年如何成为全栈工程师?
  • 原生 js 实现移动端 Touch 滑动反弹
  • 文章正在审核中 为什么使用了爬虫代理ip,真实IP还是被封禁了?
  • elasticsearch-head插件安装
  • Git 常用命令
  • [转]Introduction of iSCSI Target in Windows Server 2012
  • 【转】理解红黑树
  • Effective Java 笔记(一)
  • ES6简单总结(搭配简单的讲解和小案例)
  • express.js的介绍及使用
  • JS学习笔记——闭包
  • Python进阶细节
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 成为一名优秀的Developer的书单
  • 对象引论
  • 翻译--Thinking in React
  • 小李飞刀:SQL题目刷起来!
  • 怎样选择前端框架
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • #HarmonyOS:Web组件的使用
  • #pragma预处理命令
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (LeetCode 49)Anagrams
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (差分)胡桃爱原石
  • (四)Android布局类型(线性布局LinearLayout)
  • (算法)Game
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转)人的集合论——移山之道
  • (轉貼) UML中文FAQ (OO) (UML)
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .aanva
  • .net 受管制代码
  • .NET/C# 使用反射调用含 ref 或 out 参数的方法
  • @ConditionalOnProperty注解使用说明
  • [ C++ ] STL_vector -- 迭代器失效问题
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • []Telit UC864E 拨号上网
  • [android] 练习PopupWindow实现对话框
  • [BZOJ 3282] Tree 【LCT】
  • [C#]OpenCvSharp结合yolov8-face实现L2CS-Net眼睛注视方向估计或者人脸朝向估计
  • [C++从入门到精通] 14.虚函数、纯虚函数和虚析构(virtual)
  • [Codeforces] combinatorics (R1600) Part.2
  • [HOW TO]怎么在iPhone程序中实现可多选可搜索按字母排序的联系人选择器
  • [idea]关于idea开发乱码的配置
  • [iOS]让Xcode 4.2生成的app支持老的iOS设备(armv6)
  • [LeeCode]—Wildcard Matching 通配符匹配问题