Переменная условия pthread используется только один раз? - PullRequest
0 голосов
/ 27 апреля 2018

Я учусь использовать pthread, mutexes и условные переменные, но все идет не так, как ожидалось.

ОСНОВНАЯ РЕЗЬБА: работает непрерывно, сигнализирует рабочему потоку, читает из файла _A.

РЕЗЬБА РАБОТЫ: режим ожидания до получения сигнала, запись в файл_A, возврат в режим ожидания (должен повторяться)

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

Но по какой-то причине рабочий поток запускается только один раз . Нужно ли переустанавливать условную переменную или делать что-то еще?

Функция рабочего потока:

void* WriteTime(){
    pthread_mutex_lock(&mutex);
    pthread_cond_wait(&condition, &mutex);

    /* Open File, Write to File, Close File */

    pthread_mutex_unlock(&mutex);
}

Основная тема:

pthread_t timeThread;
pthread_create(&timeThread, NULL, &WriteTime, NULL);

while(gameConditionFulfilled == false){
    /* Print status, gets user input into line */

    /* If user enters "time", wake up WORKER_THREAD */

    if(strcmp(line, "time")==0){
        pthread_mutex_lock(&mutex);
        pthread_cond_signal(&condition);

        /* Read from file, print data, close file */ 

        pthread_mutex_unlock(&mutex);
    }
}

Кроме того, мое понимание кода выше выглядит так:

  1. Рабочий поток блокирует мьютекс. (Запускается до основного цикла)
  2. Рабочий поток cond_wait разблокирует мьютекс и ждет условия.
  3. Основной поток блокирует мьютекс.
  4. Состояние сигналов основного потока.
  5. Рабочий поток восстанавливает блокировку мьютекса, записывает в файл.
  6. Рабочий поток разблокирует мьютекс.
  7. Главный поток восстанавливает мьютекс и блокирует его.
  8. Основной поток читает файл.
  9. Основной поток разблокирует мьютекс.
  10. Рабочий поток восстанавливает блокировку?

Поведение на самом деле:

  1. Основной поток читает из файла
  2. Рабочий поток просыпается, пишет в файл, больше никогда не запускается

1 Ответ

0 голосов
/ 28 апреля 2018

Во-первых, вы хотите, чтобы в WriteTime () был какой-то цикл - возвращение приводит к вызову pthread_exit (). Когда pthread_create () запускает поток, он запускается так:

pthread_exit((*func)(arg));

Что поднимает второй вопрос - ваш компилятор должен был кричать вам об этом, поскольку ваш WriteTime () ничего не возвращает. Предупреждения полезны; им не нужно подчиняться, но вы должны понимать, почему они представлены.

Чтобы пропустить пару глав, идея условной переменной заключается в том, что она защищает «условие»; например, что есть данные, готовые для чтения или записи. Вы используете их как семафоры, но в отличие от семафоров переменные условия не имеют никакой памяти. Pthread_condition_wait () будет возвращаться только в том случае, если pthread_condition_ (signal | broadcast) () вызывается, когда поток ожидает. Если pthread_condition_signal () вызывается, когда никто не ждет, ничего не происходит. Итак, идиоматическое использование условной переменной:

lock(mutex)
while (something_hasn’t_happened) {
    wait(cond, mutex)
}
do something
unlock(mutex)
...