pthread_cond_timedwait()在FreeBSD上不起作用,返回EPERM

时间:2018-07-13 09:05:59

标签: unix pthreads freebsd

我有一个创建pthread的示例程序,等待该线程加入。该线程将调用phread_cond_timedwait()等待2秒。在Linux平台上,示例代码可以正常工作。在FreeBSD上,调用立即返回并显示EPERM错误代码。

pthread_condition_timedwait.cpp

import seaborn as sns
sns.jointplot(data=movies, x = 'CriticsRating', y = 'AudienceRating')

1 个答案:

答案 0 :(得分:2)

如果调用timedwait的线程不拥有互斥锁,则返回

EPERM。您必须在调用timedwait之前锁定互斥锁。另外,将互斥量和condvar的静态初始化移至文件作用域。

更新:如果将互斥锁初始化为检查错误的互斥锁,Linux也会以EPERM终止(因为在不持有互斥锁的情况下调用pthread_cond_wait / timedwait是UB)。

下面的修改代码:

//#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;
}

在内核SMP Debian 4.9.82-1 + deb9u3(2018-03-02)x86_64 GNU / Linux,发行版Debian GNU / Linux buster / sid上进行了测试。