Использование мьютекса и условных переменных pthreads - PullRequest
3 голосов
/ 19 июня 2010

Проблема, для которой я ищу помощь, написана в пункте №.7. Перед этим я опишу структуру моего кода.

  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, например, каждая (это отдельная функция):

функция A:

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

функция B:

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

функция C:

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

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

Заранее большое спасибо.

Ответы [ 3 ]

1 голос
/ 30 октября 2010

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

0 голосов
/ 16 марта 2011

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

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

  • function B сигналы cond2.
  • fun2 пробуждается, устанавливает var4 в true, сигналы cond4, устанавливает var2 в false, освобождает мьютекс.
  • fun2 возвращает мьютекс и повторно его высвобождает, ожидая cond2, пока var2 станет истинным.
  • function B получает мьютекс, устанавливает var2 в значение true, сигналы cond2
  • fun2 пробуждается, устанавливает var4 в значение true, сигналы cond4, устанавливает var2 в значение false, освобождает мьютекс.
  • Теперь две сигнализации cond4 объединены в одну.
0 голосов
/ 24 июня 2010

Звучит как тупик.

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

...