Вот что такое: есть массив с поплавком float bucket[5]
и 2 потока, например thread1 и thread2., когда использовать мьютекс
Thread1 отвечает за заправку bucket
, присваивая каждому элементу bucket
случайное число. Когда ковш заправляется, thread2 будет получать доступ к bucket
и читать его элементы.
Вот как я делаю работу:
float bucket[5];
pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
pthread_t thread1, thread2;
void* thread_1_proc(void*); //thread1's startup routine, tank up the bucket
void* thread_2_proc(void*); //thread2's startup routine, read the bucket
int main()
{
pthread_create(&thread1, NULL, thread_1_proc, NULL);
pthread_create(&thread2, NULL, thread_2_proc, NULL);
pthread_join(thread1);
pthread_join(thread2);
}
Ниже моя реализация для thread_x_proc:
void* thread_1_proc(void*)
{
while(1) { //make it work forever
pthread_mutex_lock(&mu); //lock the mutex, right?
cout << "tanking\n";
for(int i=0; i<5; i++)
bucket[i] = rand(); //actually, rand() returns int, doesn't matter
pthread_mutex_unlock(&mu); //bucket tanked, unlock the mutex, right?
//sleep(1); /* this line is commented */
}
}
void* thread_2_proc(void*)
{
while(1) {
pthread_mutex_lock(&mu);
cout << "reading\n";
for(int i=0; i<5; i++)
cout << bucket[i] << " "; //read each element in the bucket
pthread_mutex_unlock(&mu); //reading done, unlock the mutex, right?
//sleep(1); /* this line is commented */
}
}
Вопрос
мое право реализации? Потому что результат не такой, какой я ожидал.
...
reading
5.09434e+08 6.58441e+08 1.2288e+08 8.16198e+07 4.66482e+07 7.08736e+08 1.33455e+09
reading
5.09434e+08 6.58441e+08 1.2288e+08 8.16198e+07 4.66482e+07 7.08736e+08 1.33455e+09
reading
5.09434e+08 6.58441e+08 1.2288e+08 8.16198e+07 4.66482e+07 7.08736e+08 1.33455e+09
reading
tanking
tanking
tanking
tanking
...
Но если я раскомментировать sleep(1);
в каждой функции thread_x_proc, выход правильно, tanking
и reading
следуют друг за другом, как это:
...
tanking
reading
1.80429e+09 8.46931e+08 1.68169e+09 1.71464e+09 1.95775e+09 4.24238e+08 7.19885e+08
tanking
reading
1.64976e+09 5.96517e+08 1.18964e+09 1.0252e+09 1.35049e+09 7.83369e+08 1.10252e+09
tanking
reading
2.0449e+09 1.96751e+09 1.36518e+09 1.54038e+09 3.04089e+08 1.30346e+09 3.50052e+07
...
Почему? Должен ли я использовать sleep()
при использовании mutex
?
Это не технически корректно, так как его поведение не определено (он может танковать два раза подряд, например, «не должен»). – Valmond
Вы правы, спасибо. – Alcott
Я бы сказал, ответ на вопрос «когда использовать мьютексы?» «только тогда, когда вам нужно защитить приоритет инверсии». Я думаю, что во всех остальных случаях есть лучшие способы оценки проблемы. – elmo