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

    c 复制代码
    #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;
    }

解决方案

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

  • 示例代码如下:

    c 复制代码
    #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;
    }
相关推荐
疯狂敲代码的老刘1 分钟前
JDK 1.6到25 全版本网盘合集 (Windows + Mac + Linux)
java·linux·windows·macos·jdk
爆米花byh5 分钟前
在RockyLinux9环境的Storm2.8.3单机版安装
linux·中间件·storm
纤纡.6 分钟前
Linux 下 MySQL 数据类型与约束:第三章核心表格归纳与实战应用
linux·mysql
陈桴浮海15 分钟前
【Linux&Ansible】学习笔记合集三
linux·运维·云原生·ansible
wengqidaifeng18 分钟前
数据结构(三)栈和队列(上)栈:计算机世界的“叠叠乐”
c语言·数据结构·数据库·链表
yuanmenghao26 分钟前
Linux 性能实战 | 第 10 篇 CPU 缓存与内存访问延迟
linux·服务器·缓存·性能优化·自动驾驶·unix
EnglishJun33 分钟前
Linux系统编程(二)---学习Linux系统函数
linux·运维·学习
VekiSon40 分钟前
Linux内核驱动——设备树原理与应用
linux·c语言·arm开发·嵌入式硬件
Trouvaille ~1 小时前
【Linux】进程间关系与守护进程详解:从进程组到作业控制到守护进程实现
linux·c++·操作系统·守护进程·作业·会话·进程组
BlackQid1 小时前
深入理解指针Part5——回调函数及应用
c语言