如果我想在main中创建5个新线程并等待在开始工作之前创建所有这五个线程,我应该使用什么?
我找到了pthread_cond_wait
,也许这就是我应该使用的,但我不确定如何。有没有办法知道线程是否已创建,而不是立即进入该线程?
感谢。
答案 0 :(得分:2)
我认为您所描述的内容并不是一个好主意:您如何管理由于某些错误而未创建线程的情况?
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);
}