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

pthread_cond_timedwait 修改系统时间竟会导致其提前结束

pthread 条件变量使用注意

  • 使用 pthread_cond_timedwait 等待条件变量时,其默认使用的为系统时间,若在其等待期间修改系统时间,则会导致其提前结束。

测试步骤

  • 运行以下代码。

  • 使用 date 命令查看系统时间,假设输出为 Thu Jan 1 08:01:53 AM CST 1970

  • 使用 date -s 08:03:53 设置系统时间,程序会立刻退出,并打印 wait timed out

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <errno.h>
    #include <unistd.h>pthread_cond_t g_cond;
    pthread_mutex_t g_mutex;void* thread1_func(void* arg)
    {// 必须先获取互斥锁pthread_mutex_lock(&g_mutex);// 获取当前时间struct timespec ts;clock_gettime(CLOCK_REALTIME, &ts);// 设置等待时间为 100 秒ts.tv_sec += 100;// 等待条件变量被唤醒,或者等待时间超时printf("waiting cond signal\n");int ret = pthread_cond_timedwait(&g_cond, &g_mutex, &ts);if (ret == 0) {printf("get cond signaled\n");} else if (ret == ETIMEDOUT) {printf("wait timed out\n");} else {printf("wait failed\n");}// 解锁pthread_mutex_unlock(&g_mutex);return NULL;
    }int main()
    {pthread_cond_init(&g_cond, NULL);pthread_mutex_init(&g_mutex, NULL);// 创建线程pthread_t th1;pthread_create(&th1, NULL, thread1_func, NULL);// 等待线程结束pthread_join(th1, NULL);pthread_mutex_destroy(&g_mutex);pthread_cond_destroy(&g_cond);return 0;
    }
    

解决方案

  • 初始化条件变量时,设置其使用稳定时钟即可。

  • 示例代码如下:

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <errno.h>
    #include <unistd.h>pthread_cond_t g_cond;
    pthread_mutex_t g_mutex;void* thread1_func(void* arg)
    {// 必须先获取互斥锁pthread_mutex_lock(&g_mutex);// 获取当前时间struct timespec ts;// 此处与上文不同clock_gettime(CLOCK_MONOTONIC, &ts);// 设置等待时间为 100 秒ts.tv_sec += 100;// 等待条件变量被唤醒,或者等待时间超时printf("waiting cond signal\n");int ret = pthread_cond_timedwait(&g_cond, &g_mutex, &ts);if (ret == 0) {printf("get cond signaled\n");} else if (ret == ETIMEDOUT) {printf("wait timed out\n");} else {printf("wait failed\n");}// 解锁pthread_mutex_unlock(&g_mutex);return NULL;
    }int main()
    {pthread_condattr_t condattr;pthread_condattr_init(&condattr);// 设置使用稳定时钟pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);pthread_cond_init(&g_cond, &condattr);pthread_mutex_init(&g_mutex, NULL);// 创建线程pthread_t th1;pthread_create(&th1, NULL, thread1_func, NULL);// 等待线程结束pthread_join(th1, NULL);pthread_mutex_destroy(&g_mutex);pthread_cond_destroy(&g_cond);return 0;
    }
    
http://www.lryc.cn/news/213959.html

相关文章:

  • Linux命令超详细
  • 物理机、虚拟机、容器
  • CSS画三角形(三种方法)
  • (一)、ts 基础类型 及class类举例字符雨和实现vue的挂在#app
  • C++对象的内存分布和虚函数表
  • 小白怎么学习性能测试?一文7个知识点带你成功入门!
  • Orcad属性过滤器的使用技巧
  • 腾讯云向量数据库正式对外全量开放公测
  • Linux新建普通用户无法使用退格键与tab键
  • 【湘粤鄂车牌】
  • 华大-HC32L130F8UA 内存使用注意事项
  • 怎样才知道一个单片机的性能到极限了?
  • Android Studio的笔记--SerialPort串口通讯学习和使用
  • MySQL 启动选项和字符集
  • 社区投稿|解码Big Vector,开启Sui超扩展性的新篇章
  • Linux根目录下的目录结构及其作用详解
  • 源码和SaaS账号:租房与自建房的区别
  • Docker容器设置为自动重启
  • 速卖通卖家如何通过自己搭建测评补单系统,提高产品权重和排名?
  • 香港金融科技周2023:AIGC重塑金融形态
  • 6G关键新兴技术-智能超表面(RIS)技术演进
  • 怎么让小程序排名靠前?小程序搜索排名问题
  • 使用Postman快速复现浏览器的请求(包括生成调用代码)
  • 四则运算的正则校验
  • 【备忘录】SpringBoot+ dynamic-datasource配置自定义多数据源
  • 制作docker镜像文件
  • JAVA 中 Socket 和 WebSocket 区别
  • python 接收到一个接口的数据 是json格式 ,然后把其中键值对的一个值改掉 再返回给接口
  • ⌈C++11⌋实现一个简易计算器
  • 面试算法45:二叉树最低层最左边的值