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

Като принцип една и съща нишка не трябва да заключва mutex повече от веднъж и това се случи тук.

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