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

pthread_cond_signal调用触发线程挂起卡死问题排查

我查阅了多个相关技术主题的资料,但暂未找到当前问题的答案,非常欢迎大家提供建议。

问题背景

我目前在开发一个大型项目,出现问题的相关代码片段如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <pthread.h>

static pthread_mutex_t mutex;
static pthread_cond_t cond;

static char *timestamp()
{
    time_t rawtime;
    struct tm *timeinfo;
    char *stamp;

    time(&rawtime);
    timeinfo = localtime(&rawtime);
    stamp = asctime(timeinfo);
    stamp[strlen(stamp) - 1] = '\0';

    return stamp;
}

static void *monitor(void *ctx)
{
    int ret;
    struct timeval now;
    struct timespec timeout = { 0 };

    while (1)
    {
        gettimeofday(&now, NULL);

        timeout.tv_sec = now.tv_sec + 1;

        pthread_mutex_lock(&mutex);

        if (!(ret = pthread_cond_timedwait(&cond, &mutex, &timeout)))
        {
            printf("%s [%s] Signaled successfully!\n", timestamp(),
                __FUNCTION__);

        }
        else if (ret == ETIMEDOUT)
            printf("%s [%s] Timed out!\n", timestamp(), __FUNCTION__);

        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main()
{
    pthread_t tid;

    if (pthread_mutex_init(&mutex, NULL) < 0)
    {
        perror("mutex");
        return -1;
    }

    if (pthread_cond_init(&cond, NULL) < 0)
    {
        perror("cond");
        pthread_mutex_destroy(&mutex);
        return -1;
    }

    if (pthread_create(&tid, NULL, monitor, NULL) < 0)
    {
        perror("create()");
        pthread_cond_destroy(&cond);
        pthread_mutex_destroy(&mutex);
        return -1;
    }

    pthread_detach(tid);
    srand(time(NULL));

    while (1)
    {
        int delay = rand() % 5 + 1;

        printf("%s [main] Waker is sleeping for %d sec\n", timestamp(), delay);
        sleep(delay);

        printf("%s [main] Signaling...\n", timestamp());
        pthread_mutex_lock(&mutex);
        printf("%s [main] Lock aquired...\n", timestamp());
        pthread_cond_signal(&cond);
        printf("%s [main] Signaled. Releasing...\n", timestamp());
        pthread_mutex_unlock(&mutex);
    }

    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);

    return 0;
}
问题现象

每当[main]线程执行到pthread_cond_signal位置,且monitor线程的pthread_cond_timedwait正处于等待状态(未触发超时)时,程序就会发生卡死。

我了解到调用pthread_cond_signal前持有互斥锁是推荐的最佳实践,也查阅了多个相关技术帖子,排查过以下可能原因但均不符合我的场景:

  • 线程进入等待前提前销毁cond或mutex引发挂起
  • *spurious wakes up(虚假唤醒)*导致卡死

我也曾猜测该异常与ulimit -s/-i配置有关,但将对应参数设置为unlimited后问题仍然存在。出现卡死时[monitor]线程会和main线程一同阻塞。

更新记录

更新1

程序卡死时的运行输出如下:

Wed Jun  8 13:34:10 2022 [main] Waker is sleeping for 4 sec
Wed Jun  8 13:34:10 2022 [monitor] Timed out!
Wed Jun  8 13:34:11 2022 [monitor] Timed out!
Wed Jun  8 13:34:12 2022 [monitor] Timed out!
Wed Jun  8 13:34:13 2022 [monitor] Timed out!
Wed Jun  8 13:34:14 2022 [main] Signaling...
Wed Jun  8 13:34:14 2022 [main] Lock acquired...
/* 之后无任何输出 */

更新2

我将上述示例重构为使用pthread_cond_wait的最简逻辑,代码如下:

// monitor线程逻辑
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);

// main线程逻辑
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);

重构后调用pthread_cond_signal仍然会出现挂起,因此我怀疑问题来自操作系统层面。我目前仅知道ulimit设置的栈大小过小会引发栈溢出,进而导致这类与架构相关、在我环境中可100%复现的卡死,想了解是否存在其他会影响pthread行为的特殊系统配置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 01:15:40