название может не появиться особенно ясно, но код объясняет сам:Синхронизация результат потоков с общей переменной увеличивается на единицу и условия
int shared_variable;
int get_shared_variable() {
int result;
pthread_mutex_lock(&shared_variable_mutex);
result = shared_variable;
pthread_mutex_unlock(&shared_variable_mutex);
return result;
}
void* thread_routine(void *arg) {
while (get_shared_variable() < 5000) {
printf();
printf();
sleep(2);
int i = 0;
while (pthread_mutex_trylock(&foo_mutexes[i]) != 0) {
i++;
pthread_mutex_lock(&foo_count_mutex);
if (i == foo_count) {
pthread_mutex_unlock(&foo_count_mutex);
sleep(1); // wait one second and retry
i = 0;
}
pthread_mutex_unlock(&foo_count_mutex);
}
pthread_mutex_lock(&shared_variable_mutex);
shared_variable += 10;
pthread_mutex_unlock(&shared_variable_mutex);
}
return NULL;
}
Я передаю thread_routine
к (довольно стандартный) pthread_create
, но я У меня проблема с синхронизацией результата. В основном проблема заключается в том, что первый поток проверяет условие while, он передает, а затем проверяет другой поток, он тоже проходит. Однако, когда первая резьба заканчивается и shared_variable
достигает 5000, вторая нить еще не закончена, и она добавляет еще 10, и в конце результат заканчивается 5010 (или NUM_OF_THREADS
- 1 * 10, если я запускаю более двух), в то время как весь процесс должен закончиться в 5000.
Другая проблема заключается в том, что в // do some work
вывода я что-то на экране, так что все внутри цикла должны довольно много работы как сделки в терминах базы данных. Кажется, я не могу понять, как решить эту проблему, но, полагаю, есть что-то простое, чего мне не хватает. Заранее спасибо.
Вы не можете отпустить мьютексы до тех пор, пока критическая секция не будет завершена. Ваш критический раздел должен включать * чтение и запись переменной *, и это необходимо сделать в * одном критическом разделе. – kaylum
@kaylum, означает ли это, что критический раздел должен быть целым циклом, и, учитывая, что у меня много работы в '// do some work', не будет блокировать другие потоки так долго, чтобы преследовать цель иметь их вообще? – arnaudoff
Это зависит от того, как вы хотите его организовать. Обычно в вашем случае тело цикла будет CS. Не включая условие цикла. Но да, если «некоторая работа» длинная, тогда могут быть проблемы. Но это проблема производительности, и мы говорим только о правильности в этом вопросе. Если вы хотите обсудить производительность, вам нужно задать новый вопрос, показывающий, что именно делает «какая-то работа», прежде чем другие смогут объяснить, как лучше структурировать потоки. – kaylum