pthread_cond_timedwait忽略取消请求

pthread_cond_timedwait忽略取消请求,c,macos,pthreads,posix,C,Macos,Pthreads,Posix,pthread_cond_timedwait()有一个奇怪的问题:根据POSIX规范,它是一个取消点。但是,当我在线程上调用pthread_cancel()时,它永远不会被取消!相反,pthread_cond_timedwait()将继续正常运行。它不会锁定或执行任何操作,它只是保持运行,就好像从未调用过pthread_cancel()。但是,只要插入pthread_testcancel()调用,线程就会正确取消!如果没有对pthread_testcancel()的调用,线程永远不会被取消,尽管

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;
}
#包括
#包括
#包括
#包括
//替换函数,因为OS X似乎没有时钟
静态int clock_gettime(int clk_id,struct timespec*t)
{
现在构造timeval;
int rv=gettimeofday(&now,NULL);
如果(rv)返回rv;
t->tv_sec=now.tv_sec;
t->tv\u nsec=now.tv\u usec*1000;
返回0;
}
静态void*threadproc(void*data)
{
pthread_mutex_t mutex;
pthread_mutextatr_t attr;
pthread_cond_t cond;
pthread_mutexattr_init(&attr);
pthread_mutextatr_settype(&attr,pthread_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex,&attr);
pthread_mutexattr_destroy(&attr);
pthread_cond_init(&cond,NULL);
对于(;;){
结构timespects;
时钟获取时间(0,&ts);
//等待60毫秒
ts.tv_nsec+=60*1000000;
pthread_mutex_lock(&mutex);
pthread_cond_timedwait(&cond,&mutex,&ts);
pthread_mutex_unlock(&mutex);
#如果0
pthread_testcancel();
#恩迪夫
}
返回NULL;
}
int main(int argc,char*argv[])
{
pthread_t pthread;
pthread_create(&pthread,NULL,threadproc,NULL);
printf(“等待…\n”);
睡眠(5);
printf(“终止线程…\n”);
pthread_cancel(pthread);
pthread_join(pthread,NULL);
printf(“确定!\n”);
返回0;
}

您对代码应该如何运行的期望是正确的,事实上,它在我刚刚测试的其他系统上也能正常工作。我认为您刚刚在OSX中发现了(另一个)bug。

pthread\u cancel
在OSX 10.11.4(可能还有更早的版本)中功能正确。此外,
pthread\u join
value\u ptr
参数返回
pthread\u cancelled
,这是意料之中的结果。

请发布代码,以获得一个显示问题的小示例,并让我们知道您正在处理的平台。您是否正在“玩”线程(或其父线程)的取消类型和-状态代码?已发布。如果启用对pthread_testcancel()的调用,一切都会正常工作。否则线程将永远不会被取消。看看如果将超时时间从60秒增加到60秒会发生什么,只是为了测试。另外,添加错误检查可能是个好主意,看看还有什么可能出错。我担心:(仍然奇怪的是,取消线程这样的基本功能似乎被破坏了。这与
sem_init
在尝试使用信号量时默默地失败并导致崩溃相比根本算不了什么……这真是令人悲哀。在OSX和现在的安卓出现之前,所有*nix系统几乎完全朝着POSIX的一致性,事情已经到了你可以只写POSIX,让你的代码在任何地方都能工作的地步。但是现在,OSX和Android对标准嗤之以鼻,推出了伪POSIX实现,除了他们的围墙花园垃圾箱之外什么都不运行…-很旧。但是讨论了同样的问题。它是APEP在Mac OS中,线程\u testcancel是唯一的取消点。@jay:你在url中丢失了一个
u
。@Hasturkun:Wow,该线程充满了史诗般的失败,无法理解线程取消的原因,似乎是负责实现它的人。。。