многопоточный запуск

У меня есть 4 streamа для создания thread1, thread2, thread3 и 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); 

в отладочном режиме, порядок запущенных streamов не совпадает с порядком, указанным в исходном коде. Есть ли решение для запуска streamов с порядком, который я мог бы определить?

Порядок запуска последователен, поскольку вызовы создания происходят в том порядке, в котором они записаны.

Однако планировщик по какой-либо причине не планирует новые streamи в том порядке, в котором вы надеялись. Если порядок имеет значение, то нить не то, что вы хотите? Большое преимущество в streamах заключается в том, что они не всегда получают запланированный порядок!

Если вы действительно хотите, хотя вы можете использовать примитивы синхронизации (например, серию мьютексов или condvar), чтобы убедиться, что до определенной точки происходит в предсказуемом порядке, но с этого момента заказ все равно будет доходить до прихотей планировщик. В качестве примера этот код гарантирует, что каждый stream будет печатать свой идентификатор в том порядке, в котором они были созданы:

 #include  #include  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, чтобы сделать сон / пробуждение возможным. Он транслирует все темы, которые затем проверяют, какой из них стоит дальше. Вы можете проектировать как систему, которая пропускает трансляцию, но это усложняет ситуацию для относительно небольшого выигрыша.

Вы также можете добавить дополнительную синхронизацию, если это необходимо в других точках, но чем больше вы синхронизируете, тем меньше в них есть streamи.

В идеале, если что-то должно произойти в предсказуемом порядке, они должны быть выполнены до появления нитей, а не сразу после появления нитей, например:

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

так что к моменту создания нитей вам все равно, какой из них действительно получит шанс запустить в первую очередь.

Я не думаю, что вам действительно нравится, какой stream выполняется первым. Если вам нужен только уникальный идентификатор для четырех streamов, проверьте pthread_self. Чтобы иметь последовательные идентификаторы, вызовите идентификатор-распределитель из streamа; или сгенерировать идентификатор и передать его в качестве параметра пользователя при вызове pthread_create.

здесь после решения, которое я использовал

 #include  #include  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 } } 
 Move 'pthread_create(thread2,NULL,thread_func2,NULL);' into thread_func1() Move 'pthread_create(thread3,NULL,thread_func2,NULL);' into thread_func2() Move 'pthread_create(thread4,NULL,thread_func2,NULL);' into thread_func3() 

Это ОЧЕНЬ близко к другому вопросу, опубликованному недавно, и точно так же, как ошибаться .. «странно»