Unix pthread_cond_timedwait()不在FreeBSD上工作,返回EPERM
我有一个示例程序,它创建一个pthread,等待线程加入。线程将调用phread_cond_timedwait()等待2秒。在Linux平台上,示例代码运行良好。在FreeBSD上,调用会立即返回EPERM错误代码 pthread_condition_timedwait.cppUnix pthread_cond_timedwait()不在FreeBSD上工作,返回EPERM,unix,pthreads,freebsd,Unix,Pthreads,Freebsd,我有一个示例程序,它创建一个pthread,等待线程加入。线程将调用phread_cond_timedwait()等待2秒。在Linux平台上,示例代码运行良好。在FreeBSD上,调用会立即返回EPERM错误代码 pthread_condition_timedwait.cpp \define\u BSD\u源 #包括 #包括 #包括 #包括 #包括 #包括 void*线程处理器(void*ptr){ pthread_cond_t cond=pthread_cond_初始值设定项; pthrea
\define\u BSD\u源
#包括
#包括
#包括
#包括
#包括
#包括
void*线程处理器(void*ptr){
pthread_cond_t cond=pthread_cond_初始值设定项;
pthread\u mutex\u t mutex=pthread\u mutex\u初始值设定项;
结构timespects;
结构timeval-tp;
gettimeofday(&tp,NULL);
ts.tv_sec=tp.tv_sec;
ts.tv\u nsec=tp.tv\u usec*1000;
ts.tv_sec+=2;
//调用pthread_cond_timedwait()等待2秒
int rcode=pthread\u cond\u timedwait(&cond,&mutex,&ts);
if(rcode==ETIMEDOUT)
printf(“由于超时而终止\n”);
else if(rcode==EPERM)
printf(“因EPERM终止”);
其他的
printf(“返回代码为%d\n”,rcode);
返回NULL;
}
int main(int argc,字符**argv){
pthread\u t线程;
//开线
pthread_create(&thread,NULL,&thread_handler,NULL);
//等待线程完成
pthread_join(线程,NULL);
返回0;
}
如果调用timedwait的线程不拥有互斥锁,则返回EPERM。在调用timedwait之前,必须锁定互斥锁。另外,将mutex和condvar的静态初始化移动到文件范围
更新:如果您将互斥体初始化为一个错误检查互斥体,Linux也将以EPERM终止(因为在不持有互斥体的情况下调用pthread_cond_wait/timedwait是很困难的)
修改代码如下:
//#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex;
void *thread_handler(void *ptr){
struct timespec ts;
struct timeval tp;
gettimeofday(&tp, NULL);
ts.tv_sec = tp.tv_sec;
ts.tv_nsec = tp.tv_usec*1000;
ts.tv_sec += 2;
//Invoke pthread_cond_timedwait() to wait for 2 seconds
int rcode = pthread_cond_timedwait(&cond, &mutex, &ts);
if (rcode == ETIMEDOUT)
printf("Terminated due to time out\n");
else if (rcode == EPERM)
printf("Terminated due to EPERM\n");
else
printf("Return code is %d\n", rcode);
return NULL;
}
int main(int argc, char** argv){
pthread_mutexattr_t mta;
pthread_mutexattr_init(&mta);
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&mutex, &mta);
pthread_t thread;
// start the thread
pthread_create(&thread, NULL, &thread_handler, NULL);
// wait for thread to finish
pthread_join(thread, NULL);
return 0;
}
定义源代码
#包括
#包括
#包括
#包括
#包括
#包括
pthread_cond_t cond=pthread_cond_初始值设定项;
pthread_mutex_t mutex;
void*线程处理器(void*ptr){
结构timespects;
结构timeval-tp;
gettimeofday(&tp,NULL);
ts.tv_sec=tp.tv_sec;
ts.tv\u nsec=tp.tv\u usec*1000;
ts.tv_sec+=2;
//调用pthread_cond_timedwait()等待2秒
int rcode=pthread\u cond\u timedwait(&cond,&mutex,&ts);
if(rcode==ETIMEDOUT)
printf(“由于超时而终止\n”);
else if(rcode==EPERM)
printf(“因EPERM终止”);
其他的
printf(“返回代码为%d\n”,rcode);
返回NULL;
}
int main(int argc,字符**argv){
pthread_mutexttr_mta;
pthread_mutexattr_init(&mta);
pthread_mutextatr_settype(&mta,pthread_MUTEX_ERRORCHECK);
pthread_mutex_init(&mutex,&mta);
pthread\u t线程;
//开线
pthread_create(&thread,NULL,&thread_handler,NULL);
//等待线程完成
pthread_join(线程,NULL);
返回0;
}
在内核SMP Debian 4.9.82-1+deb9u3(2018-03-02)x86_64 GNU/Linux,发行版Debian GNU/Linux buster/sid上测试。@Yaswanth不要先尝试锁定互斥锁。@Erik Alapä谢谢。它起作用了!使用锁定的互斥锁工作。不知道为什么它会在Linux上传递。是的,调用cond_wait/timedwait而不锁定互斥锁是很奇怪的,而且也是UB。从手册页:pthread_cond_wait()和pthread_cond_timedwait()函数用于阻塞条件变量。它们被调用线程锁定的互斥锁调用,否则将导致未定义的行为。如果您打开错误检查互斥锁,Linux可能会发出错误信号。
//#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex;
void *thread_handler(void *ptr){
struct timespec ts;
struct timeval tp;
gettimeofday(&tp, NULL);
ts.tv_sec = tp.tv_sec;
ts.tv_nsec = tp.tv_usec*1000;
ts.tv_sec += 2;
//Invoke pthread_cond_timedwait() to wait for 2 seconds
int rcode = pthread_cond_timedwait(&cond, &mutex, &ts);
if (rcode == ETIMEDOUT)
printf("Terminated due to time out\n");
else if (rcode == EPERM)
printf("Terminated due to EPERM\n");
else
printf("Return code is %d\n", rcode);
return NULL;
}
int main(int argc, char** argv){
pthread_mutexattr_t mta;
pthread_mutexattr_init(&mta);
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&mutex, &mta);
pthread_t thread;
// start the thread
pthread_create(&thread, NULL, &thread_handler, NULL);
// wait for thread to finish
pthread_join(thread, NULL);
return 0;
}