2010-06-18 2 views
3

Проблема, о которой я хочу найти, написана в пункте №. 7. До этого я описываю структуру своего кода.Использование мьютексов и переменных состояния pthreads

  1. Из main(), две нити thread1 и thread2 создаются и инициализируются две функции fun1() и fun2() соответственно.
  2. У меня есть мьютекс с именем lock_mutex и переменные условия, названные cond1, cond2, cond3 и cond4.
  3. У меня есть глобальные логические переменные var1, var2, var3 и var4 инициализированы ложь.
  4. fun1(), как следующее:

    void fun1(){ 
    while(1){ 
    pthread_mutex_lock(&lock_mutex); 
    while(var1 is false) 
        pthread_cond_wait(&cond1,&lock_mutex); 
    //do some work 
    set var3 = true; 
    pthread_cond_signal(&cond3); 
    set var1=false; 
    pthread_mutex_unlock(&lock_mutex); 
    } 
    } 
    
  5. fun2() выглядит следующим образом:

    void fun2(){ 
    while(1){ 
    pthread_mutex_lock(&lock_mutex); 
    while(var2 is false) 
        pthread_cond_wait(&cond2,&lock_mutex); 
    //do some work 
    set var4 = true; 
    pthread_cond_signal(&cond4); 
    set var2=false; 
    pthread_mutex_unlock(&lock_mutex); 
    } 
    } 
    
  6. Есть функции в моем коде, которые держат lock_mutex, сделать какую-то работу и сигнал cond1 и cond2 при необходимости , как это (каждая отдельная функция):

функция А:

pthread_mutex_lock(&lock_mutex); 
    //do some work 
    set var1= true; 
    pthread_cond_signal(&cond1); 
    pthread_mutex_unlock(&lock_mutex); 

функция В:

pthread_mutex_lock(&lock_mutex); 
//do some work 
set var2= true; 
pthread_cond_signal(&cond2); 
pthread_mutex_unlock(&lock_mutex); 

функция С:

pthread_mutex_lock(&lock_mutex) 
//do some work 
while(var3 is false) 
pthread_cond_wait(&cond3,&lock_mutex); 
//do more work 
set var3=false; 
pthread_mutex_unlock(&lock_mutex); 

функция D:

pthread_mutex_lock(&lock_mutex) 
//do some work 
while(var4 is false) 
pthread_cond_wait(&cond4,&lock_mutex); 
//do more work 
set var4= false; 
pthread_mutex_unlock(&lock_mutex); 

7. fun1() и fun2() многократно сигнализируются функцией A и функцией B. Я ожидаю, что fun1() и fun2() вызовут функцию C и функцию D каждый раз, когда они сигнализируются.

Но fun1() и fun2() проснулись только в первый раз. После этого они входят в цикл while, приобретают блокировку и ждут сигнала неопределенно долго и не просыпаются, несмотря на сигнализацию.

Я не могу понять причину этой проблемы и был бы очень благодарен за любое предложение. Если есть какие-либо хорошие методы отладки/инструменты для такого рода программ, любезно отсылайте меня к ним.

С большим благодарением.

ответ

0

Это звучит как тупик.

Если один поток получает блокировку мьютекса, а затем ожидает, что переменная будет установлена, Как другой поток получает блокировку мьютекса для установки переменной?

+0

Любая идея о том, как я мог ее решить? – vpk

+0

Я бы сказал, проверьте http://publib.boulder.ibm.com/iseries/v5r1/ic2924/index.htm?info/apis/users_76.htm, они используют серию операторов printf для отслеживания потока кода, возможно, этот подход прольет свет на то, что происходит –

1

Ответ на вопрос г-на Грейвса состоит в том, что pthread_cond_wait автоматически блокирует мьютекс при блокировке.

0

Сигнальная переменная условия не означает, что блокирующий поток получает блокировку и начинает работать немедленно, это означает, что она разбужена, и когда пожелает планировщик, она даст процессорное время блокирующего потока.

Так, что я думаю, что здесь происходит следующее:

  • function B сигналов cond2.
  • fun2 пробуждается, устанавливает var4 в true, сигналы cond4, устанавливает var2 в false, освобождает мьютексы.
  • fun2 reacquires мьютексы, и relequases его, ожидая на cond2 для var2, чтобы стать правдой.
  • function B получает семафор, устанавливает var2 истинно, сигналы cond2
  • fun2 пробуждается, устанавливает var4 истинно, сигналы cond4, устанавливает var2 ложь, освобождает семафор.
  • Теперь две сигнализации cond4 были сведены в один.
Смежные вопросы