pthread_cond_timedwait忽略取消请求

时间:2012-05-14 14:00:48

标签: c macos pthreads posix

pthread_cond_timedwait()有一个奇怪的问题:根据POSIX规范,它是一个取消点。但是,当我在线程上调用pthread_cancel()时,它永远不会被取消!相反,pthread_cond_timedwait()继续正常运行。它没有锁定或任何东西,它只是保持运行,好像pthread_cancel()从未被调用过。但是,只要插入pthread_testcancel()调用,线程就会被正确取消!如果没有调用pthread_testcancel(),虽然我一直在调用pthread_cond_timedwait(),但线程永远不会被取消。

有人知道这里出了什么问题吗?非常感谢!

编辑:代码来了:

#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>

// replacement function because OS X doesn't seem to have clock_gettime()
static int clock_gettime(int clk_id, struct timespec* t)
{
    struct timeval now;
    int rv = gettimeofday(&now, NULL);

        if(rv) return rv;

    t->tv_sec = now.tv_sec;
        t->tv_nsec = now.tv_usec * 1000;

    return 0;
}

static void *threadproc(void *data)
{
    pthread_mutex_t mutex;
    pthread_mutexattr_t attr;               
    pthread_cond_t cond;

    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);

    pthread_mutex_init(&mutex, &attr);      
    pthread_mutexattr_destroy(&attr);

    pthread_cond_init(&cond, NULL);

    for(;;) {

        struct timespec ts;

        clock_gettime(0, &ts);

        // wait 60ms
        ts.tv_nsec += 60 * 1000000;

        pthread_mutex_lock(&mutex);
        pthread_cond_timedwait(&cond, &mutex, &ts);
        pthread_mutex_unlock(&mutex);   

#if 0
        pthread_testcancel();
#endif      
    }

    return NULL;    
}

int main(int argc, char *argv[])
{
    pthread_t pThread;

    pthread_create(&pThread, NULL, threadproc, NULL);

    printf("Waiting...\n");
    sleep(5);
    printf("Killing thread...\n");

    pthread_cancel(pThread);
    pthread_join(pThread, NULL);

    printf("Ok!\n");

    return 0;
}

2 个答案:

答案 0 :(得分:4)

您对代码应该如何表现的期望是正确的,事实上它在我刚刚测试的其他系统上按预期工作。我想你刚刚在OSX中发现了(又一个)错误。

答案 1 :(得分:0)

pthread_cancel在OS X 10.11.4(以及可能的早期版本)中正常运行。此外,value_ptr的{​​{1}}参数会返回pthread_join,这应该是预期的。