Waitforsingleobject и waitformultipleobjects эквивалентны в linux

я переношу applciation из windows в linux. Я сталкиваюсь с проблемой в отношении WaitForSingleObject и WaitForMultipleObjects интерфейсы.

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

Я проверил pthread_cond_timedwait, но мы должны указать абсолютное время для этого.

как я могу реализовать это в Unix?

4 ответов


палкой pthread_cond_timedwait и использовать clock_gettime. Например:

struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 10; // ten seconds
while (!some_condition && ret == 0)
    ret = pthread_cond_timedwait(&cond, &mutex, &ts);

оберните его в функцию, если вы хотите.


UPDATE: дополнение ответа на основе наших комментариев.

POSIX не имеет ни одного API для ожидания "всех типов" событий/объектов, как это делает Windows. У каждого свои функции. Самый простой способ уведомить поток о завершении-использовать атомарные переменные / операции. Например:

Главная нить:

// Declare it globally (argh!) or pass by argument when the thread is created
atomic_t must_terminate = ATOMIC_INIT(0);

// "Signal" termination by changing the initial value
atomic_inc(&must_terminate); 

вторичный поток:

// While it holds the default value
while (atomic_read(&must_terminate) == 0) {
    // Keep it running...
}
// Do proper cleanup, if needed
// Call pthread_exit() providing the exit status

Другой альтернативой является отправка запроса на отмену с помощью pthread_cancel. Отменяемый поток должен был вызвать pthread_cleanup_push для регистрации любого необходимого обработчика очистки. Эти обработчики вызываются в обратном порядке, в котором они были зарегистрированы. Никогда не звоните pthread_exit из обработчика очистки, потому что это неопределенное поведение. Состояние выхода отмененного потока -PTHREAD_CANCELED. Если вы выбираете эту альтернативу, я рекомендую вам читать в основном о точках и типах отмены.

и последнее, но не менее, называя pthread_join будет делать текущий блок потока, пока поток, переданный аргументом, не завершится. В качестве бонуса, вы получите статус выхода потока.


для чего это стоит, мы (NeoSmart Technologies) только что выпустили библиотеку с открытым исходным кодом (MIT licensed) под названием pevents, который реализует WIN32 ручной и автоматический сброс событий на POSIX и включает в себя клоны WaitForSingleObject и WaitForMultipleObjects.

хотя я лично советую вам использовать многопоточные и сигнальные парадигмы POSIX при кодировании на машинах POSIX, pevents дает вам другой выбор, если вам это нужно.


Я понимаю, что это старый вопрос, но для всех, кто натыкается на него, этот источник предполагает, что pthread_join() делает то же самое, что WaitForSingleObject():

http://www.ibm.com/developerworks/linux/library/l-ipc2lin1/index.html

удачи!


на WaitForMultipleObjects С false WaitAll попробуйте это:

#include <unistd.h>
#include <pthread.h>
#include <stdio.h>

using namespace std;

pthread_cond_t condition;
pthread_mutex_t signalMutex;
pthread_mutex_t eventMutex;
int finishedTask = -1;

void* task(void *data)
{
    int num = *(int*)data;
    // Do some
    sleep(9-num);
    // Task finished
    pthread_mutex_lock(&eventMutex); // lock until the event will be processed by main thread
    pthread_mutex_lock(&signalMutex); // lock condition mutex
    finishedTask = num; // memorize task number
    pthread_cond_signal(&condition);
    pthread_mutex_unlock(&signalMutex); // unlock condtion mutex
}

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

    pthread_cond_init(&condition, NULL);
    pthread_mutex_init(&signalMutex, NULL); // First mutex locks signal
    pthread_mutex_init(&eventMutex, NULL); // Second mutex locks event processing

    int numbers[10];

    for (int i = 0; i < 10; i++) {
        numbers[i] = i;
        printf("created %d\n", i); // Creating 10 asynchronous tasks
        pthread_create(&thread[i], NULL, task, &numbers[i]);
    }

    for (int i = 0; i < 10;)
    {
        if (finishedTask >= 0) {
            printf("Task %d finished\n", finishedTask); // handle event
            finishedTask = -1; // reset event variable
            i++;
            pthread_mutex_unlock(&eventMutex); // unlock event mutex after handling
        } else {
            pthread_cond_wait(&condition, &signalMutex); // waiting for event
        }
    }

    return 0;
}