/ / Как работи този пример pthread_cond_wait ()? - c, multithreading, concurrency, pthreads, posix

Как работи този пример pthread_cond_wait ()? - c, multithreading, concurrency, pthreads, posix

Получих следния код от този уебсайт:

https://computing.llnl.gov/tutorials/pthreads/#Abstract

Този прост пример кодекс демонстрира използването наняколко Pthread състоянието на променливите рутинни процедури. Основната рутина създава три нишки. Две от нишките изпълняват задачи и актуализират променлива "брой". Най- третата нишка чака, докато променливата на броя достигне определена стойност.

Въпросът ми е как се гарантира кодът по-долуче една от двете работни нишки не блокира мутекса, преди да се заключи конецът на наблюдателя? Ако това се случи, конците на наблюдателя ще бъдат заключени и pthread_cond_wait(&count_threshold_cv, &count_mutex) никога няма да се обади?

Аз съм под предлог pthread_create() всъщност започва и конецът. Единствената причина за това е, защото pthread_create() за нишката на наблюдателя започва преди pthread_create() за двете работни нишки ?! Със сигурност това не е чугун, а графикът може да доведе до началото на нишката на работника преди нишката на наблюдателя? Дори компилаторът евентуално би могъл да пренареди тези кодове на код?

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define NUM_THREADS  3
#define TCOUNT 10
#define COUNT_LIMIT 12

int     count = 0;
int     thread_ids[3] = {0,1,2};
pthread_mutex_t count_mutex;
pthread_cond_t count_threshold_cv;

void *inc_count(void *t)
{
int i;
long my_id = (long)t;

for (i=0; i<TCOUNT; i++) {
pthread_mutex_lock(&count_mutex);
count++;

/*
Check the value of count and signal waiting thread when condition is
reached.  Note that this occurs while mutex is locked.
*/
if (count == COUNT_LIMIT) {
pthread_cond_signal(&count_threshold_cv);
printf("inc_count(): thread %ld, count = %d  Threshold reached.n",
my_id, count);
}
printf("inc_count(): thread %ld, count = %d, unlocking mutexn",
my_id, count);
pthread_mutex_unlock(&count_mutex);

/* Do some "work" so threads can alternate on mutex lock */
sleep(1);
}
pthread_exit(NULL);
}

void *watch_count(void *t)
{
long my_id = (long)t;

printf("Starting watch_count(): thread %ldn", my_id);

/*
Lock mutex and wait for signal.  Note that the pthread_cond_wait
routine will automatically and atomically unlock mutex while it waits.
Also, note that if COUNT_LIMIT is reached before this routine is run by
the waiting thread, the loop will be skipped to prevent pthread_cond_wait
from never returning.
*/
pthread_mutex_lock(&count_mutex);
while (count<COUNT_LIMIT) {
pthread_cond_wait(&count_threshold_cv, &count_mutex);
printf("watch_count(): thread %ld Condition signal received.n", my_id);
count += 125;
printf("watch_count(): thread %ld count now = %d.n", my_id, count);
}
pthread_mutex_unlock(&count_mutex);
pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
int i, rc;
long t1=1, t2=2, t3=3;
pthread_t threads[3];
pthread_attr_t attr;

/* Initialize mutex and condition variable objects */
pthread_mutex_init(&count_mutex, NULL);
pthread_cond_init (&count_threshold_cv, NULL);

/* For portability, explicitly create threads in a joinable state */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&threads[0], &attr, watch_count, (void *)t1);
pthread_create(&threads[1], &attr, inc_count, (void *)t2);
pthread_create(&threads[2], &attr, inc_count, (void *)t3);

/* Wait for all threads to complete */
for (i=0; i<NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
printf ("Main(): Waited on %d  threads. Done.n", NUM_THREADS);

/* Clean up and exit */
pthread_attr_destroy(&attr);
pthread_mutex_destroy(&count_mutex);
pthread_cond_destroy(&count_threshold_cv);
pthread_exit(NULL);

}

Отговори:

2 за отговор № 1

Въпросът ми е как - по-долу кодът гарантира, че една от двете работни нишки не блокира> mutexта, преди нишката на наблюдателя да се заключи върху нея?

Кодът не трябва да гарантира това. Той не зависи от нишката на наблюдател, която извиква pthread_cond_wait ().

Проверката на нишката наблюдава count<COUNT_LIMIT, това е действителното условие, което се грижи за нишката - или по-скоро обратното, кога count >= COUNT_LIMIT - нишката на наблюдателя знае, че другите нишки са завършени.

Променливата за състоянието pthread, използвано в pthread_cond_wait() е необходимо само в случай, че нишките не са направени, така че нишката на наблюдателя може да бъде заспивана и се събуди, за да провери състоянието, от което се грижи.

Това каза, че примерът изглежда тъп глупав, не е съвсем ясно какво иска да постигне контурите, които правят count += 125;


0 за отговор № 2

коментарът във вашия код обяснява, че не е нужно да се притеснявате за това:

Също така, имайте предвид, че ако се достигне COUNT_LIMIT, преди да се стартира тази рутина чакащата нишка, цикълът ще бъде пропуснат, за да се избегне pthread_cond_wait от никога не се връща.

всъщност, ако забележите, докато цикълът се изпълнява само ако COUNT_LIMIT все още не е постигнато count, Ако случаят е такъв, pthread_cond_signal не се нарича изобщо.