c - 多线程启动顺序

标签 c linux pthreads

我有 4 个线程来创建线程 1、线程 2、线程 3 和线程 4:

pthread_create(thread1,NULL,thread_func1,NULL);
pthread_create(thread2,NULL,thread_func2,NULL);
pthread_create(thread3,NULL,thread_func3,NULL);
pthread_create(thread4,NULL,thread_func4,NULL);

查看调试,启动线程的顺序与源代码中定义的不一样。 是否有一种解决方案可以按照我可以定义的顺序启动线程?

最佳答案

启动顺序连续的,因为创建调用是按照它们编写的顺序发生的。

但是无论出于何种原因,调度程序都没有按照您希望的顺序调度新启动的线程。如果订单很重要,也许线程不是您想要的?线程的一大优势是它们并不总是按顺序安排!

如果你真的想要,虽然你可以使用同步原语(例如一系列互斥量,或一个 condvar)来确保直到某个点以可预测的顺序发生,但从那一点开始,顺序仍然会下降到调度器的突发奇想。作为示例,此代码保证每个线程将按照创建它们的顺序打印其 ID:

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

static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void sync_threads(const int num, int *cur) {
  pthread_mutex_lock(&mut);
  while (*cur != num) {
    pthread_cond_wait(&cond, &mut);
  }
  // Do work that must happen in order here:
  printf("Thread: %d\n", num);
  ++*cur;
  pthread_mutex_unlock(&mut);
  pthread_cond_broadcast(&cond);
}

static int num = 1;

void *thread1(void *d) {
  sync_threads(1,&num);
  while (1); // Rest of work happens whenever
  return NULL;
}

void *thread2(void *d) {
  sync_threads(2,&num);
  while (1);
  return NULL;
}

void *thread3(void *d) {
  sync_threads(3,&num);
  while (1);
  return NULL;
}

void *thread4(void *d) {
  sync_threads(4,&num);
  while (1);
  return NULL;
}

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

我使用 while(1); 来模拟一些真实的工作。它使用保护“当前”线程的互斥锁来实现这一点,即初始化顺序,然后是一个 condvar 来使 sleep /唤醒成为可能。它向所有线程广播,然后线程检查下一个线程。您可以设计为跳过广播的系统,但这会使事情变得复杂,但 yield 相对较小。

如果需要,您还可以在其他点添加更多同步,但是同步越多,首先拥有线程的意义就越小。

理想情况下,如果事情需要以可预测的顺序发生,它们应该在 产生线程之前完成,而不是在线程产生时立即完成,例如:

fixed_init_for_thread1();
fixed_init_for_thread2();
fixed_init_for_thread3();
fixed_init_for_thread4();

pthread_create(thread1,NULL,thread_func1,NULL);
pthread_create(thread2,NULL,thread_func2,NULL);
pthread_create(thread3,NULL,thread_func3,NULL);
pthread_create(thread4,NULL,thread_func4,NULL);

这样,在创建线程时,您不关心哪个线程实际上有机会先运行。

关于c - 多线程启动顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10616787/

相关文章:

c++ - 如何使用 C++、Pam 和 Ubuntu 添加自定义双因素身份验证?

c++ - posix 中的健壮 rwlock

c - (gvim 8271) IBUS 警告

c - 如何使用任意数量的 scanf() 格式说明符?

c++ - "reserved for any use"是什么意思?

python - 在 Ubuntu 12.04 中安装 psycopg2 时出错

linux - gdb: 虚拟内存耗尽

c++ - pthread_mutex_t 作为类成员导致死锁

c - Libclang API 获取定义在不同文件中的函数定义

c - shell(bash) 如何在 linux 中工作,即它如何处理后台运行进程