pthread_cond_timedwait () не работает над FreeBSD, возвращает EPERM

Это связано с тем, что механизм JavaScript заставляет любой тип в логическом состоянии при тестировании условия. Как будто вы делали

// Coerce it to a boolean using !!
if (!!window.XMLHttpRequest) {
   xmlhttp = new XMLHttpRequest();
}
1
задан smeso 13 July 2018 в 09:40
поделиться

1 ответ

EPERM возвращается, если поток, который вызывает timedwait, не имеет мьютекса. Вы должны заблокировать мьютекс перед вызовом timedwait. Кроме того, переместите статическую инициализацию мьютекса и конвара в область файлов.

UPDATE: если вы инициализируете мьютекс как муфту для проверки ошибок, Linux также завершится с EPERM (так как UB вызывает вызов 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;
}

Протестировано на ядре SMP Debian 4.9.82-1 + deb9u3 (2018-03-02) x86_64 GNU / Linux, дистрибутив Debian GNU / Linux buster / sid.

2
ответ дан Erik Alapää 17 August 2018 в 13:18
поделиться
  • 1
    Работает с блокировкой мьютекса. Интересно, почему он переходит на Linux. – Yashwanth T 16 July 2018 в 06:04
  • 2
    Да, вызов cond_wait / timedwait без блокировки мьютекса является странным, а также UB. Из manpage pubs.opengroup.org/onlinepubs/7908799/xsh/… : функции pthread_cond_wait () и pthread_cond_timedwait () используются для блокировки переменной условия. Они вызывают с мьютексом, заблокированным вызывающим потоком, или результатом будет неопределенное поведение. Возможно, если вы включите мьютексы с проверкой ошибок, Linux сообщит об ошибке. – Erik Alapää 16 July 2018 в 08:05
Другие вопросы по тегам:

Похожие вопросы: