pthread_mutex_lock вызывает тупик

Я использую приведенный выше код для увеличения счетчика, используя 2 потока, которые независимо принимают блокировку mut и счетчик увеличения. Я столкнулся с тупиком после того, как потоки войдут в эту функцию.

 pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

 void *increment_counter(void *counter_addr)
{
    int max = MAX_COUNTER_VALUE;
    int iter;
    int counter;

    for(iter=0;iter< max ;iter++)
   // LOCK  
    pthread_mutex_lock(&mut);
    counter++;
    // UNLOCK 
    pthread_mutex_unlock(&mut);
    return NULL; 
}

Может ли кто-нибудь сказать мне, где именно я ошибаюсь?


person Shehbaz Jaffer    schedule 29.09.2012    source источник
comment
вероятно, вы хотели int* counter = counter_addr и ++*counter.   -  person Jens Gustedt    schedule 29.09.2012


Ответы (4)


Вы пытаетесь заблокировать мьютекс max раз, затем увеличить counter и один раз отпустить.

Пытаться:

for(iter=0;iter< max ;iter++)
{
  // LOCK  
  pthread_mutex_lock(&mut);
  counter++;
  // UNLOCK 
  pthread_mutex_unlock(&mut);
}
return NULL; 
person Mat    schedule 29.09.2012
comment
Ох ... Это была плохая ошибка программирования ... спасибо, что указали на нее. :) - person Shehbaz Jaffer; 29.09.2012

Возможно, это то, что вы пытались сделать:

int max = MAX_COUNTER_VALUE;
int iter;
int counter;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

void *increment_counter(void *counter_addr)


{

  pthread_mutex_lock(&mut);    
  for(iter=0;iter< max ;iter++)  
       counter++;
  pthread_mutex_unlock(&mut);
  return NULL; 
}
  • 2 или более потока совместно используют только данные глобальной области или данные, расположенные в куче (malloc).
  • 2 или более потоков не имеют общих переменных, определенных в стеке, эти данные уникальны для каждого потока, и нет необходимости блокировать их.

Приглашаем вас прочитать в ответах, что передается, а что нет и т. Д.

person 0x90    schedule 29.09.2012

Как правило, один и тот же поток не должен блокировать мьютекс более одного раза, и вот что здесь произошло.

person lang2    schedule 29.09.2012

инициализация блокировки очень важна. Если вы не инициализируете свои блокировки правильным значением, ваш код сломается. Один из способов инициализации блокировки следующий:

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

Также вы можете выполнять эту задачу динамически, используя следующий код:

int rc = pthread_mutex_init(&lock, NULL);
assert(rc == 0); // always check success!

Помимо инициализации блокировки, вы должны проверить код возврата pthread_mutex_lock, чтобы увидеть, не сработает он или нет, так как в случае сбоя несколько потоков могут войти в критическую секцию. Для этой цели вы можете использовать код, похожий на этот, который проверяет код возврата pthread_mutex_lock:

// Use this to keep your code clean but check for failures
// Only use if exiting program is OK upon failure
void Pthread_mutex_lock(pthread_mutex_t *mutex) {
int rc = pthread_mutex_lock(mutex);
assert(rc == 0);
}
person Mona Jalal    schedule 26.10.2013