【问题标题】:What can I use to wait for all threads to be created?我可以用什么来等待所有线程被创建?
【发布时间】:2018-11-07 09:34:00
【问题描述】:

如果我想在 main 中创建 5 个新线程并等待所有这 5 个线程都创建完毕,然后再开始其中的工作,我应该使用什么?

我找到了pthread_cond_wait,也许这就是我应该使用的,但我不确定如何使用。有什么方法可以知道创建了一个线程而不立即进入该线程?

谢谢。

【问题讨论】:

  • 你为什么需要/想要等待这个?
  • 也许你想要pthread_barrier_wait和相关功能。但是pthread_thread_create 正在创建一个线程立即所以不清楚你真正想要什么
  • 我需要它,因为一旦创建了线程,我需要在特定时间内做某事,并希望所有线程同时启动。而且我知道 pthread_thread_create 会立即创建线程,但它不会同时创建所有 5 个线程。
  • 您无需等待。最后一个线程创建函数之后的下一行将是线程创建之后。
  • 我认为这不是一个好主意:您将如何处理由于某些错误而没有创建线程的情况?

标签: c multithreading unix pthreads


【解决方案1】:

我认为您所描述的不是一个好主意:您将如何管理由于某些错误而未创建线程的情况?

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_signalpthread_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);
}

【讨论】:

    猜你喜欢
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    相关资源
    最近更新 更多