7
votes

pthread_cond_timpedwait ()

void wait(int timeInMs)
{
    struct timespec timeToWait;
    timeToWait.tv_sec = 5;
    timeToWait.tv_nsec = timeInMs*1000;

    int rt;

    pthread_mutex_lock(&fakeMutex);
    rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait);
    pthread_mutex_unlock(&fakeMutex);
}
I'm using this code to try to get a thread to wait around for a bit, but it doesn't work at all.  No errors, it just doesn't make the program execute any slower.I was thinking maybe each thread needs to have it's own condition and mutex, but that really doesn't make sense to me.

1 commentaires

Peu importe cet exemple, mais NSEC = 1 000 000 * msec.


7 Réponses :


2
votes

Ce code ne dort pas, il vérifie une condition pendant un moment. Comme vous n'êtes probablement pas probablement réglé, OK, cela revient simplement immédiatement.

Si vous n'êtes pas disposé à synchroniser les threads autour d'un signal, pthread_cond _wait n'est pas ce dont vous avez besoin. Vérifiez ici Comment fonctionne les variables de la condition.

Si vous souhaitez dormir avec des secondes de précision, utilisez Dormez

Si vous souhaitez dormir avec des microsecondes Precision Utilisez Sélectionnez avec Timevals.


2 commentaires

Mais le sommeil arrête un processus entier, j'ai besoin du fil d'attente.


Utilisez "SELECT" avec un TIMEVAL et NULL pour les paramètres de lecture, d'écriture, d'exception. Notez que, à l'aide de SELECT, SELLUME fonctionne uniquement sur Linux, dans Windows Select Retourne immédiatement si seulement un paramètre Timeval est fourni.



3
votes

Considérant que vous utilisez TimesPec, et votre objectif n'est pas de se synchroniser, mais d'attendre, je vous suggérerais de nanosleep.

#include <time.h>

.
.
.

  struct timespec remain;
  remain.tv_sec = 5;
  remain.tv_nsec = timeInMs * 1000;

  do {
    if ( nanosleep( &remain, &remain ) == 0 || errno != EINTR ) {
      break;
    }
  } while ( 1 );

.
.
.


0 commentaires

19
votes

Utilisation de n'importe quelle variante de sommeil, le comportement n'est pas garanti. Tous les fils peuvent également dormir car le noyau n'est pas au courant des différents threads.

Une solution plus sûre et plus propre à utiliser est pthread_cond_timpedwait code>. Vous avez utilisé l'API de manière incorrecte. Voici un meilleur exemple: P>

pthread_mutex_t fakeMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER;

void mywait(int timeInMs)
{
    struct timespec timeToWait;
    struct timeval now;
    int rt;

    gettimeofday(&now,NULL);


    timeToWait.tv_sec = now.tv_sec+5;
    timeToWait.tv_nsec = (now.tv_usec+1000UL*timeInMs)*1000UL;

    pthread_mutex_lock(&fakeMutex);
    rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait);
    pthread_mutex_unlock(&fakeMutex);
    printf("\nDone\n");
}

void* fun(void* arg)
{
    printf("\nIn thread\n");
    mywait(1000);
}

int main()
{
    pthread_t thread;
    void *ret;

    pthread_create(&thread, NULL, fun, NULL);
    pthread_join(thread,&ret);
}


1 commentaires

Pour moi, GetTimeofday (& Maintenant, NULL) n'a pas fonctionné, mais cela a fait (pour 200ms): horloge_gettime (horloge_realtime et Timeowait); Timeetowait.tv_nsec + = 200000000UL; Timeetowait.tv_nsec% = 1000000000UL; Timeetowait.tv_sec + = Timeetowait.tv_nsec <200000000UL? dix;



19
votes

Le pthread_cond_timpedwait fonctionne un absolu temps, pas une heure relative. Il faut le temps que vous voulez arrêter d'attendre, pas combien de temps vous voulez attendre.


0 commentaires

1
votes

Voici un exemple où j'ai créé un thread à partir d'une boucle principale qui effectue une numérisation d'un répertoire et avoir un délai d'attente de 5 secondes. Et la signalisation du fil se produit en utilisant une variable conditionnelle qui est globale. Nous continuons à vérifier ce signal de thread: xxx


0 commentaires

10
votes

pthread_cond_timpedwait utilise du temps absolu, alors besoin de:

  • Utilisez GetTimeofDay pour récupérer l'heure actuelle. li>
  • TimesPec.TV_NSEC est nanoseconde, il ne peut pas être grand de 1 seconde. Li>
  • TIMEVAL.TV_USEC est microseconde (1000 nanosecondes). LI>
  • Timesinms est milliseconde: 1 milliseconde = 1000 microsecondes = 1000 * 1000 nanosecondes. P>

    void wait(int timeInMs)
    {
        struct timeval tv;
        struct timespec ts;
    
        gettimeofday(&tv, NULL);
        ts.tv_sec = time(NULL) + timeInMs / 1000;
        ts.tv_nsec = tv.tv_usec * 1000 + 1000 * 1000 * (timeInMs % 1000);
        ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000);
        ts.tv_nsec %= (1000 * 1000 * 1000);
    
        int n = pthread_cond_timedwait(&condition, &mutex, &ts);
        if (n == 0)
            // TODO: singaled
        else if (n == ETIMEDOUT)
            // TODO: Time out.
    }
    


0 commentaires

2
votes

Référence principale: http://pubs.opengroup.org/onlinePubs/ 009695299 / Fonctions / Pthread_cond_timpedwait.html

Correction du code de andrewrk ci-dessus

Je peux confirmer Adrian May que GettimeOdday ne fonctionne pas correctement! Le comportement de code de andrewrk à l'intérieur d'un fil infini comme celui-ci xxx

est imprévisible: il fonctionne environ 700 fois plus jusqu'à ce qu'il bloque!

la version correcte du code de andrewrk est: xxx < / pré>


2 commentaires

C'est la seule réponse qui a fonctionné et c'était bien que vous ayez réparé le poste avec les plus avantageux.


Merci @johnjesus pour tester et confirmer!