C ++ простой вопрос о потоках - PullRequest
2 голосов
/ 23 сентября 2011

Я пишу простую программу производителя / потребителя, чтобы лучше понимать c ++ и многопоточность.В моей ветке, которая управляла потребителем, у меня были первые две строки:

    pthread_cond_wait(&storageCond, &storageMutex);
    pthread_mutex_lock(&storageMutex);

Но программа застряла, вероятно, в тупике.Затем я переключил строки:

    pthread_mutex_lock(&storageMutex);
    pthread_cond_wait(&storageCond, &storageMutex);

И это сработало.Может кто-нибудь, пожалуйста, помогите мне понять, почему это сработало, а первое - нет?

Спасибо.

Ответы [ 3 ]

5 голосов
/ 23 сентября 2011

со страницы руководства pthread_cond_wait (http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_wait.html):

Они вызываются с мьютексом, заблокированным вызывающим потоком или неопределенным поведение приведет.

Я предлагаю вам использовать хорошую библиотеку-оболочку, такую ​​как boost::threads, или когда у вас есть доступ к C ++ 11, вы используете средства std::. Поскольку они используют такие вещи, как RAII, с ними гораздо проще работать, особенно если они неопытны в программировании потоков.

1 голос
/ 23 сентября 2011

Как только поток возобновляет работу из условной переменной wait, он повторно вызывает блокировку мьютекса.Вот почему первый пример программы застрял.

Идея состоит в том, чтобы всегда делать cond_wait () внутри блокировки мьютекса.Cond_wait () снимет блокировку и начнет атомарное ожидание (чтобы вы не пропустили cond_signal () из другого потока), а при получении сигнала cond_wait () повторно получит мьютекс, чтобы убедиться, что в вашем критическом разделе есть только один потокработает в нем.

HTH, эта схема блокировки известна как Monitor .

1 голос
/ 23 сентября 2011

Это немного упрощено, но вам нужно заблокировать мьютекс, который вы используете, чтобы выполнить ожидание условия - это как защита состояния многопоточной гонки.Если вам нужно хорошее описание того, почему, проверьте справочную страницу UNIX с помощью команды "man pthread_cond_wait", и она даст хорошую длинную речь:)

pthread_cond_wait(&storageCond, &storageMutex); //Wants mutex you don't have locked.
pthread_mutex_lock(&storageMutex);              //Get mutex after its too late.

pthread_mutex_lock(&storageMutex);              //Get mutex first.
pthread_cond_wait(&storageCond, &storageMutex); //Do cond wait with mutex you have.
...