WaitForSingleObject et WaitForMultipleObjects équivalent sous linux

je suis en train de migrer une application de windows vers linux. Je suis face à problème concernant WaitForSingleObject et WaitForMultipleObjects interfaces.

dans mon application je lance plusieurs threads où tous les threads attendent les événements du processus parent ou tournent périodiquement pendant toutes les secondes.

j'ai vérifié pthread_cond_timedwait, mais nous devons spécifier le temps absolu pour cela.

Comment puis-je implémenter ceci dans Unix?

25
demandé sur jww 2010-04-27 11:59:43
la source

4 ответов

Coller pthread_cond_timedwait et utiliser clock_gettime. Par exemple:

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);

l'Envelopper dans une fonction si vous le souhaitez.


mise à jour: compléter la réponse basée sur nos commentaires.

POSIX n'a pas une seule API pour attendre "tous les types" d'événements/objets comme Windows le fait. Chacun a ses propres fonctions. La façon la plus simple de notifier un thread pour la terminaison est d'utiliser des variables/opérations atomiques. Par exemple:

principal fil de discussion:

// 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); 

thread secondaire:

// 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

une autre alternative est d'envoyer une demande d'Annulation en utilisant pthread_cancel. Le fil annulé doit avoir appelé pthread_cleanup_push pour enregistrer tout nettoyeur nécessaire. Ces gestionnaires sont appelés dans l'ordre inverse de leur enregistrement. Ne jamais appeler pthread_exit d'un gestionnaire de nettoyage, parce que c'est un comportement non défini. Le statut de sortie d'un thread annulé est PTHREAD_CANCELED. Si vous optez pour cette solution, je vous recommande pour en savoir plus sur les points et les types d'annulation.

Et le dernier mais non le moindre, l'appel de pthread_join va faire le bloc de thread courant jusqu'à ce que le thread passé par l'argument se termine. En prime, vous obtiendrez le statut de sortie du thread.

13
répondu jweyrich 2010-04-28 05:46:55
la source

je me rends compte que c'est une vieille question maintenant, mais pour quiconque trébuche dessus, cette source suggère que pthread_join() fait effectivement la même chose que WaitForSingleObject():

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

Bonne chance!

1
répondu eskimo9 2012-04-11 09:16:09
la source

WaitForMultipleObjects faux WaitAll essaye ceci:

#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;
}
1
répondu Sorcerer 2015-10-19 11:43:22
la source