2016-04-08 1 views
0

название может не появиться особенно ясно, но код объясняет сам:Синхронизация результат потоков с общей переменной увеличивается на единицу и условия

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 вывода я что-то на экране, так что все внутри цикла должны довольно много работы как сделки в терминах базы данных. Кажется, я не могу понять, как решить эту проблему, но, полагаю, есть что-то простое, чего мне не хватает. Заранее спасибо.

+0

Вы не можете отпустить мьютексы до тех пор, пока критическая секция не будет завершена. Ваш критический раздел должен включать * чтение и запись переменной *, и это необходимо сделать в * одном критическом разделе. – kaylum

+0

@kaylum, означает ли это, что критический раздел должен быть целым циклом, и, учитывая, что у меня много работы в '// do some work', не будет блокировать другие потоки так долго, чтобы преследовать цель иметь их вообще? – arnaudoff

+0

Это зависит от того, как вы хотите его организовать. Обычно в вашем случае тело цикла будет CS. Не включая условие цикла. Но да, если «некоторая работа» длинная, тогда могут быть проблемы. Но это проблема производительности, и мы говорим только о правильности в этом вопросе. Если вы хотите обсудить производительность, вам нужно задать новый вопрос, показывающий, что именно делает «какая-то работа», прежде чем другие смогут объяснить, как лучше структурировать потоки. – kaylum

ответ

0

Этот ответ может быть или не быть тем, чем вы являетесь. Потому что, как поясняется в комментариях, ваше описание ожидаемого поведения программы является неполным. Без точного ожидаемого поведения трудно дать полный ответ. Но так как вы спрашиваете, вот возможная структура программы на основе показанного кода. Основным принципом является то, что критическая секция для shared_variable должна быть минимальной и полной.

int shared_variable; 

void* thread_routine(void *arg) 
{ 
    while (1) { 

     pthread_mutex_lock(&shared_variable_mutex); 
     if (shared_variable >= 5000) { 
      pthread_mutex_unlock(&shared_variable_mutex); 
      break; 
     } 
     shared_variable += 10; 
     pthread_mutex_unlock(&shared_variable_mutex); 

     /* Other code that doesn't use shared_variable goes here */ 

    } 

    return NULL; 
} 
Смежные вопросы