pthreads - заставить поток работать - PullRequest
1 голос
/ 14 июня 2011

У меня есть функция, которая вызывается из основного потока:

void create_thread() {    
    pthread_t bg_thread;
    pthread_create(&bg_thread, NULL, run_in_background, NULL);

    //wait here
    pthread_mutex_lock(&MAIN_MUTEX);
    pthread_cond_wait(&wakeUpMainThread, &MAIN_MUTEX);
    pthread_mutex_unlock(&MAIN_MUTEX);

    pthread_cond_signal(wakeUpBgThread);
}

Вот краткая версия функции, которая запускается в фоновом потоке:

void* run_in_background(void* v) {                   
    pthread_mutex_t mutex;
    pthread_cond_t  cond;
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    //NOTE: wakeUpBgThread == cond
    save_condition_and_mutex(&cond, &mutex);

    pthread_mutex_lock(&mutex);
    {
        pthread_cond_signal(&wakeUpMainThread);

        while( run_condition ) {
            pthread_cond_wait(&cond, &mutex);

            do_smth();
        }
    }
    pthread_mutex_unlock(&mutex);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);

    pthread_exit(NULL);
}

Итак, цельis:

1. Create a thread in the main one.
2. Make the main thread sleep until the signal from that thread.
3. Make the background thread sleep until the signal from the main thread.
4. Invoke the background thread from the main one.

Проблема заключается в следующем: иногда после того, как планировщик

 pthread_cond_signal(&wakeUpMainThread);

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

Вопрос: есть ли способ заставить фоновый поток выполнять код до тех пор, пока

pthread_cond_wait(&cond, &mutex);

Ответы [ 4 ]

2 голосов
/ 14 июня 2011

Ваш звонок на pthread_mutex_lock в create_thread должен состояться до pthread_create, а не после него. В противном случае у вас есть состояние гонки.

1 голос
/ 14 июня 2011

Использовать семафор?Сигналы семафора не теряются - они просто увеличивают счетчик, и поэтому фоновый поток будет запускать аган после того, как семафор получит сигнал, даже если он еще не успел его дождаться.* Ргдс, Мартин

0 голосов
/ 13 июля 2011

Вы не блокируете мьютекс перед вашим сигналом в основном потоке.Если вам нужно предсказуемое поведение - вы должны заблокировать один и тот же мьютекс перед ожиданием вызова и сигналом вызова.

0 голосов
/ 14 июня 2011

Похоже, вам лучше всего использовать условие.Имейте мьютекс и условие.Main инициализирует оба, захватывает мьютекс, создает поток и переходит в состояние сна.Ребенок захватывает блокировку (после того, как основное ожидание выполнит условие) выполняет работу (или, альтернативно, выполняет работу, затем захватывает блокировку), а затем сигнализирует о состоянии (вы можете решить, следует ли снять блокировку до или после сигнала - важный битэто что ты его схватил).Затем Main просыпается и продолжает обработку.

pthread_cond_wait () и друзья - это то, на что вы смотрите.

...