【问题标题】:multi thread launch arrangement多线程启动安排
【发布时间】:2012-05-16 10:11:24
【问题描述】:

我有 2 个线程来创建线程 1 和线程 2。创建线程时:

pthread_create(&thread1, NULL, &function_th1, NULL);
pthread_create(&thread2, NULL, &function_th2, NULL);

thread2在thread1之前启动,我正在寻找在thread2之前启动thread1的解决方案。

不寻找此解决方案:

pthread_create(&thread2, NULL, &function_th2, NULL);
pthread_create(&thread1, NULL, &function_th1, NULL);

【问题讨论】:

  • 您能否发布更多背景信息,说明为什么要在 thread2 之前启动 thread1?

标签: c linux multithreading


【解决方案1】:

线程创建调用的发出时间和线程实际开始执行的时间之间没有关系。这完全取决于实现、操作系统等。这就是为什么您会看到这两个线程实际上是以看似随机的顺序开始的。

如果您需要线程 1 在线程 2 之前启动,您可能对某些事件有一些数据/逻辑依赖性。在这种情况下,您应该使用条件变量来告诉线程 2 何时实际开始执行。

// condition variable
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
// associated mutex
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// state for condition variable
int shouldWait = 1;

...

void* function_th1(void* p) {
     // execute something

     // signal thread 2 to proceed
     pthread_mutex_lock(&mutex);
     shouldWait = 0;
     pthread_cond_signal(&cond);
     pthread_mutex_unlock(&mutex);

     // other stuff
}

void* function_th2(void* p) {
     // wait for signal from thread 1
     pthread_mutex_lock(&mutex);
     while(shouldWait) {
         pthread_cond_wait(&cond, &mutex);
     }
     pthread_mutex_unlock(&mutex);

     // other stuff
}    

【讨论】:

  • 在检查或设置该条件时也使用同步。在这种情况下,互斥锁就可以了。
  • +1,尤其是在更改条件和信号时正确锁定,我见过很多人忘记了。
  • @Tudor,对,但我在你发布代码之前发表了评论)))
  • @superM:是的,我知道,我刚才提到了,以防您对代码有其他 cmets。 :)
  • 从线程 1 创建线程 2 的简单解决方案有什么问题?
【解决方案2】:

移动 'pthread_create(&thread2, NULL, &function_th2, NULL);'到“function_th1”函数的顶部。

这肯定会达到您的要求,不需要复杂的信号。

你所要求的是否是你真正想要或需要的,是另一回事。

【讨论】:

  • 嗯...因为我没有看到任何状态被传递,这可能是个好主意!
  • @Tudor 您的解决方案很好,我已经认为我可以优先运行我的线程。 Linux上是否存在这样的解决方案?因为我开发了一个多线程应用程序。
  • @Ahmed ZRIBI:您可以为 pthread 设置优先级,但这并不能解决您的问题。它不能保证线程 1 在线程 2 之前运行。
  • @AhmedZRIBI - 那么,正如我们所怀疑的那样,您真正想要或需要的并不是您所要求的。显然,如果线程2是由线程1创建的,那么绝对保证线程1会先运行,即。你要求什么。你能更清楚你真正想要什么以及为什么吗?
  • @Martin James:我有几个线程一个接一个地启动,并在一个包含一组动作的链表上操作,以便启动这些线程的顺序非常重要。
【解决方案3】:

在我建议的解决方案之后

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

static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static bool wait = TRUE;

void thread_sync() {
  pthread_mutex_lock(&mut);
  wait = FALSE;
  pthread_cond_signal(&cond);
  pthread_mutex_unlock(&mut);
}
void thread_wait_sync() {
  pthread_mutex_lock(&mut);
  if (wait==TRUE)
  {
      pthread_cond_wait(&cond,&mut);
  }
  wait = TRUE;
  pthread_mutex_unlock(&mut);
}

void *thread1(void *d) {
  thread_sync();
  while (1); // Rest of work happens whenever
  return NULL;
}

void *thread2(void *d) {
  thread_sync();
  while (1);
  return NULL;
}

void *thread3(void *d) {
  thread_sync();
  while (1);
  return NULL;
}

void *thread4(void *d) {
  while (1);
  return NULL;
}

int main() {
  pthread_t t1,t2,t3,t4;
  pthread_create(&t1, NULL, thread1, NULL);
  thread_wait_sync();
  pthread_create(&t2, NULL, thread2, NULL);
  thread_wait_sync();
  pthread_create(&t3, NULL, thread3, NULL);
  thread_wait_sync();
  pthread_create(&t4, NULL, thread4, NULL);
  while(1) {
    // some work
  }
}

【讨论】:

  • 我没有收到此代码。你在做broadcastsignal 但没人在等吗?
  • 此代码错误地使用了条件变量。如果在主线程未等待时调用pthread_cond_signal,则不会发生任何事情,您的代码将死锁,等待永远不会到达的信号。另外需要一个标志;例如,请参阅 Tudor 的答案。
  • 确实如此。如果在 pthread_cond_wait 之前调用 pthread_cond_signal,我添加了一个布尔变量以避免等待。代码更新
猜你喜欢
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-16
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
相关资源
最近更新 更多