непредсказуемое поведение потоков - PullRequest
0 голосов
/ 07 декабря 2010

Я пытаюсь реализовать этот простой пример того, как синхронизировать потоки, используя библиотеку pthread:

#include <iostream>
#include <pthread.h>

using namespace std ;

static pthread_mutex_t locker;
pthread_cond_t cond;
volatile bool ok=false;


void *func2(void *data)
{
int i;
for(i=0;i<100;i++)
{
    pthread_mutex_lock (&locker);
    cout << "1";
    pthread_mutex_unlock(&locker);
    if(i==10)
    {
        ok=true;
        pthread_cond_signal(&cond);
    }

}

pthread_exit(0);

  }

void *fun1(void *data)
{
int i;
for(i=0;i<100;i++)
{

    if(ok==false){
    pthread_cond_wait(&cond, &locker);
    }

    pthread_mutex_lock (&locker);
    cout << "2";
    pthread_mutex_unlock(&locker);
}

pthread_exit(0);
   }




   int main(void)
  {


pthread_t thread1, thread2;
void *retour_thread;


pthread_mutex_init (&locker, NULL);
pthread_cond_init(&cond, NULL);

if(pthread_create (&thread1, NULL, fun1, NULL) < 0)
{
    cout << "problem thread";
    exit(1);
}
if(pthread_create (&thread2, NULL, func2, NULL) < 0)
{
    cout << "problem thread";
    exit(1);
}


(void)pthread_join(thread1,&retour_thread);
(void)pthread_join(thread2,&retour_thread);

return 0;
    }

, что я должен увидеть, это func1 ждать, пока условие (ok == true) затем обработает func2.... но то, что я получаю, непредсказуемо и не синхронизировано !!!

любая помощь и спасибо в адвенсе

Ответы [ 3 ]

1 голос
/ 07 декабря 2010
  • Правило № 1 для условных переменных: дождитесь условной переменной, удерживая блокировку (во время ожидания, когда блокировка будет снята)
  • Правило № 2 для условных переменных: всегда используйте «пока условие, подождите»для условной переменной "(избегая ложных сигналов)
0 голосов
/ 07 декабря 2010

Мой опыт работы с pthread_cond_wait таков, что он немного непредсказуем.Хотя есть несколько вещей, которые вы можете попробовать.

Например, вместо использования if (ok == false) попробуйте использовать while (ok == false), чтобы оно повторяло ожидание, если что-то заставляет еговозвращаться рано (всегда хорошая практика).Также учтите, что нет никакой согласованности в том, как долго будет работать поток - например, вполне возможно, что thread1 выдаст сразу после возврата из ожидания, что даст вам некоторые непредсказуемые результаты ... Попробуйте опубликовать то, что происходиттак что мы можем рассмотреть это более подробно.

Кроме того, делайте то, что сказал Джанм;)

0 голосов
/ 07 декабря 2010

Вам необходимо получить мьютекс перед вызовом pthread_cond_wait, и после возврата pthread_cond_wait мьютекс будет восстановлен.Ваш fun1 () должен выглядеть примерно так:

void *fun1(void *data)
{
    int i;
    for(i=0;i<100;i++)
    {
        pthread_mutex_lock (&locker);
        if(ok==false)
            pthread_cond_wait(&cond, &locker);

        cout << "2";
        pthread_mutex_unlock(&locker);
    }
}

Обновление:

У вас есть раса, где func2 () может сигнализировать быстрее, чем fun1 ().Если вам нужны альтернативные выходы «1» и «2», вам нужна обратная связь в обоих направлениях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...