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

C pthreads疑问:禁用线程取消状态时sleep为何被取消请求中断?

pthread取消状态设为DISABLE时,sleep仍被中断的问题

我正在学习C语言与POSIX API,尤其是pthreads线程库。遇到一个意外情况:尽管线程已通过pthread_setcancelstate将取消状态设置为PTHREAD_CANCEL_DISABLE,线程内的sleep调用仍被主线程的pthread_cancel取消请求中断。

测试代码

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <assert.h>

static void *thread(void *arg)
{
    int oldstate;

    printf("other thread: started\n");

    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
    printf("other thread: started doing thing that can't be canceled\n");

    errno = 0;
    sleep(10);
    if (errno)
        perror("sleep");

    printf("other thread: finished doing thing that can't be canceled\n");
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);

    printf("other thread: exiting\n");

    return NULL;
}

int main(void)
{
    pthread_t thr;
    void *res;

    pthread_create(&thr, NULL, thread, NULL);
    printf("main: created other thread\n");

    printf("main: letting other thread work for 3 seconds...\n");
    sleep(3);
    printf("main: canceling other thread\n");
    pthread_cancel(thr);

    printf("main: joining with other thread\n");
    res = NULL;
    pthread_join(thr, &res);
    if (res == PTHREAD_CANCELED)
        printf("main: canceled other thread\n");
    else
        printf("main: other thread result: %p\n", res);

    printf("main: exiting\n");

    return 0;
}

预期输出

main: created other thread
main: letting other thread work for 3 seconds...
other thread: started
other thread: started doing thing that can't be canceled
main: canceling other thread
main: joining with other thread
other thread: finished doing thing that can't be canceled
other thread: exiting
main: canceled other thread
main: exiting

实际输出

main: created other thread
main: letting other thread work for 3 seconds...
other thread: started
other thread: started doing thing that can't be canceled
main: canceling other thread
main: joining with other thread
sleep: Interrupted system call
other thread: finished doing thing that can't be canceled
other thread: exiting
main: canceled other thread
main: exiting

这似乎不符合预期。取消请求并非信号,为何会导致sleep被中断?我原本预期这段代码的执行逻辑等价于用如下代码替代sleep(10):

// before `thread`:
static pthread_mutex_t sleep_mut = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t sleep_cv = PTHREAD_COND_INITIALIZER;

static void *sleep_thread(void *arg)
{
    int sleep_for = *((int *) arg);

    sleep(sleep_for);
    pthread_cond_broadcast(&sleep_cv);

    return NULL;
}

static void *thread(void *arg)
{
    // ...
    // instead of `sleep`:
    pthread_mutex_lock(&sleep_mut);
    pthread_t sleep_thr;
    int sleep_for = 10;
    pthread_create(&sleep_thr, NULL, sleep_thread, &sleep_for);
    pthread_cond_wait(&sleep_cv, &sleep_mut);
    pthread_mutex_unlock(&sleep_mut);
    // ...
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:22:02