Я следующий исходный код (адаптировано из моего оригинального кода):pthread_mutex_unlock не атомное
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include "pthread.h"
#define MAX_ENTRY_COUNT 4
int entries = 0;
bool start = false;
bool send_active = false;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condNotEmpty = PTHREAD_COND_INITIALIZER;
pthread_cond_t condNotFull = PTHREAD_COND_INITIALIZER;
void send()
{
for (;;) {
if (!start)
continue;
start = false;
for(int i = 0; i < 11; ++i) {
send_active = true;
pthread_mutex_lock(&mutex);
while(entries == MAX_ENTRY_COUNT)
pthread_cond_wait(&condNotFull, &mutex);
entries++;
pthread_cond_broadcast(&condNotEmpty);
pthread_mutex_unlock(&mutex);
send_active = false;
}
}
}
void receive(){
for(int i = 0; i < 11; ++i){
pthread_mutex_lock(&mutex);
while(entries == 0)
pthread_cond_wait(&condNotEmpty, &mutex);
entries--;
pthread_cond_broadcast(&condNotFull);
pthread_mutex_unlock(&mutex);
}
if (send_active)
printf("x");
}
int _tmain(int argc, _TCHAR* argv[])
{
pthread_t s;
pthread_create(&s, NULL, (void *(*)(void*))send, NULL);
for (;;) {
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&condNotEmpty, NULL);
pthread_cond_init(&condNotFull, NULL);
start = true;
receive();
pthread_mutex_destroy(&mutex);
mutex = NULL;
pthread_cond_destroy(&condNotEmpty);
pthread_cond_destroy(&condNotFull);
condNotEmpty = NULL;
condNotFull = NULL;
printf(".");
}
return 0;
}
Проблема заключается в том, как следует: время от времени последней разблокировки в функции отправки не закончена до метод приема продолжается. В моем исходном коде мьютексы расположены в объектах, которые удаляются после выполнения задания. Если метод отправки не завершился с последней разблокировкой, мьютексы недействительны, и моя программа вызывает сбои в разблокировке.
Поведение может быть легко воспроизведено путем запуска программы: каждый раз, когда «x» дублируется, метод приема почти завершен, и метод отправки «зависает» в вызове разблокировки.
Я скомпилирован с VS2008 и VS2010 - оба результата одинаковы.
pthread_mutex_unlock не является атомарным, это решит проблему. Как я могу решить эту проблему? Любые комментарии приветствуются ...
С наилучшими пожеланиями
Майкл
Я не уверен, что полностью понимаю проблему, но вам не нужно ждать окончания потока отправки (`pthread_join (s, NULL);`), прежде чем пытаться уничтожить мьютекс, на который он опирается ? – 2010-12-08 12:57:20
Также вам не нужно/не следует инициализировать мьютексы как со статическим инициализатором `PTHREAD_MUTEX_INITIALIZER`, так и с вызовом` pthread_mutex_init`. (Попытка инициализировать уже инициализированный мьютекс приводит к неопределенному поведению.) – 2010-12-08 13:01:38
Посылающий поток - это поток, который никогда не заканчивается в моем приложении (фактически это поток ввода-вывода). – michael 2010-12-08 13:12:02