Я не думаю, что это хорошая идея, которую вы описали: как бы вы справились с ситуацией, когда поток не был создан из-за каких-то ошибок?
pthread_cond_wait
может быть элегантным решением, но вы должныиспользовать условие ожидания для каждого из 5 потоков;плюс условие больше похоже на триггер: когда что-то случится, сделай что-нибудь.Из того, что вы описали, вы хотите что-то, что больше похоже на начальное условие.
Одно простое решение - использовать глобальную переменную, которая является счетчиком, и каждый раз, когда создается один из 5 потоков, счетчик увеличивается:
В любом случае, чтобы увидеть, правильно ли создан поток, вы можете использовать что-то вроде этого:
if ((err = pthread_create (&threadID, NULL, threadFunction, NULL))!=0)
{
printf("some error\n");
}
else
{
global_counter++;
}
Затем в каждой из функций потока используйте цикл, который ничего не делает, и чье условие циклапроверяет, меньше ли переменная счетчика, чем число потоков, которые вы хотите создать:
while (global_counter<5)
{
;
}
..../rest of the thread functions
ПРИМЕЧАНИЕ: это опасно, потому что, если вы не будете осторожны в выборе значений переменной, вы застрянете в 5 бесконечных циклах.
Также вам следует использовать мьютекс некоторого типа (возможно, мьютекс для чтения / записи), поскольку глобальный счетчик записывается одним потоком, а читается многими.
ВАЖНОЕ РЕДАКТИРОВАНИЕ :Кроме того, вы должны справиться с ситуацией, когда один из потоков не создан (например, уничтожение уже созданных потоков и не создание других), в противном случае другие будут снова застревать в этом бесконечном цикле.
РЕДАКТИРОВАТЬ2
Я знаю, что об этом уже давно спрашивали, но на самом деле есть и другие решения, возможно, более элегантные.
Одним из них является то, что в вашем вопросе используется pthread_cond_wait()
впоток, который должен ждать инициализации, и pthread_cond_broadcoast()
/ pthread_cond_signal()
в потоке инициализации.
Разница между pthread_cond_signal
и pthread_cond_broadcast
заключается в следующем: в первом единственный поток получитзаблокировать и выполнить.Остальные все еще должны ждать.При pthread_cond_broadcast
все потоки будут разблокированы одновременно.Например:
pthread_mutex_t mtx;
pthread_cond_t cv;
void* threadFunction(void*);
int main()
{
pthread_mutex_lock(&mtx);
for (int i=0; i<5; i++)
{
if ((err = pthread_create (&threadID, NULL, threadFunction, NULL))!=0)
{
printf("some error\n");
}
}
pthread_cond_broadcast(&cv);
pthread_mutex_unlock(&mtx);
}
void* threadFunction(void*)
{
pthread_mutex_lock(&mtx);
pthread_cond_wait(&cv, &mtx);
do_things();
pthread_mutex_unlock(&mtx);
}
Другое решение, на мой взгляд, заключается в использовании блокировки записи и записи: в начале main thread
блокирует мьютекс чтения-записи при записи.Другие потоки попытаются заблокировать его (например, в режиме чтения, если вы хотите разбудить их одновременно), но при блокировке записи они будут заблокированы.
Когда все потоки созданы, разблокировка main
а остальные могут выполнить:
pthread_rwlock_t lock;
void* threadFunction(void*);
int main()
{
pthread_rwlock_init(&lock, ...);
//First acquire the write lock:
if ((res = pthread_rwlock_wrlock(&lock)!=0)
{
exit(1);
}
for (int i=0; i<5; i++)
{
if ((err = pthread_create (&threadID, NULL, threadFunction, NULL))!=0)
{
printf("some error\n");
}
}
pthread_rwlock_unlock(&lock);
pthread_rwlock_destroy(&lock);
}
void* threadFunction(void*)
{
pthread_rwlock_rdlock(&lock);
do_things();
pthread_rwlock_unlock(&lock);
}