2009-08-03 6 views
2

Предполагая, что у меня есть программа C с 3 POSIX потоков, разделяя глобальную переменную, семафор, и переменной условия, два из которых выполняются следующие psuedocode:Гарантированный приносит с pthread_cond_wait и pthread_cond_signal

...process data... 
pthread_mutex_lock(&mutex); 
variable = data_ptr; 
pthread_cond_signal(&cond); 
pthread_mutex_unlock(&mutex); 

И третий эксплуатация:

while(1) { 
    while(variable == NULL) { 
     pthread_mutex_wait(&cond, &mutex); 
    } 
    printf("Data is %d", *variable); 
} 

Можно ли предположить, что третий поток будет видеть данные от каждого из первых двух?

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

ответ

12

Нет такой вещи, как pthread_mutex_wait. Я предполагаю, что вы имеете в виду:

pthread_mutex_lock(&mutex); 
/* ... */ 
while (1) { 
    while (variable == NULL) 
    pthread_cond_wait(&cond, &mutex); 
    printf("Data is %d", *variable); 
} 
/* ... */ 
pthread_mutex_unlock(&mutex); 

Нет никакой гарантии, что в третьем потоке будут отображаться данные обоих. pthread_cond_signal пробудит третий поток, но он может не принять мьютекс немедленно. Один из других авторов может сначала принять мьютекс. Однако вы можете получение идеальными, что вы хотите с немного больше работы:

void put(int *p) { 
    pthread_mutex_lock(&mutex); 
    while (variable) 
    pthread_cond_wait(&cond_empty, &mutex); 
    variable = p; 
    pthread_cond_signal(&cond_full); 
    pthread_mutex_unlock(&mutex); 
} 

int *get() { 
    int *ret; 

    pthread_mutex_lock(&mutex); 
    while (!variable) 
    pthread_cond_wait(&cond_full, &mutex); 
    ret = variable; 
    variable = NULL; 
    pthread_cond_signal(&cond_empty); 
    pthread_mutex_unlock(&mutex); 

    return ret; 
} 

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

+0

К сожалению, это должно быть pthread_cond_wait. – Edward

1

Вот что я нашел в standard:

4,13 Планирование политики

политика планирования влияет на процесс или нить порядок:

[...]

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

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

Так что это, по-видимому, не определено. Это неудивительно: вообще говоря, вы не можете предположить ничего о том, какой runnable поток будет запланирован для запуска.

0

Согласно pthread_cond_wait странице руководства

нити (ы), которые должны разблокированы бороться за взаимную блокировку в соответствии с политикой планирования (если это применимо), а также, как если бы каждый из них называется pthread_mutex_lock().

К сожалению, насколько я могу судить, нет никакой политики планирования, которая дает вам поведение, которое вы хотите.

+2

Строго говоря, SCHED_FIFO или SCHED_RR со статическим приоритетом выше, чем потоки записи, в однопроцессорной системе. Но на SMP вы все равно можете гоняться за замком. – bdonlan