Ответ 1
int main()
{
pthread_t tid[2];
for (int i = 0; i < 2; i++) {
pthread_create(&tid[i], NULL, routine, NULL);
}
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
Я намерен запустить 2 потока в основном потоке, и основной поток должен дождаться завершения всех двух дочерних потоков, вот как я это делаю.
void *routine(void *arg)
{
sleep(3);
}
int main()
{
for (int i = 0; i < 2; i++) {
pthread_t tid;
pthread_create(&tid, NULL, routine, NULL);
pthread_join(&tid, NULL); //This function will block main thread, right?
}
}
В приведенном выше коде pthread_join
действительно заставляет основной поток ждать дочерних потоков, но проблема в том, что второй поток не будет создан до завершения первого. Это не то, что я хочу.
Я хочу, чтобы 2 потока создавались сразу в основном потоке, а затем основной поток ждет их завершения. Кажется, что pthread_join
не может сделать трюк, не так ли?
Я подумал, может быть, через semaphore
я могу выполнить эту работу, но любым другим способом?
int main()
{
pthread_t tid[2];
for (int i = 0; i < 2; i++) {
pthread_create(&tid[i], NULL, routine, NULL);
}
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
Сначала создайте все потоки, затем присоедините их все:
pthread_t tid[2];
/// create all threads
for (int i = 0; i < 2; i++) {
pthread_create(&tid[i], NULL, routine, NULL);
}
/// wait all threads by joining them
for (int i = 0; i < 2; i++) {
pthread_join(tid[i], NULL);
}
В качестве альтернативы, используйте переменную pthread_attr_t
, используйте pthread_attr_init (3), затем pthread_attr_setdetachedstate (3)
затем перейдите к pthread_create (3) второй аргумент. Thos создаст потоки в отдельном состоянии. Или используйте pthread_detach
, как описано в Jxh answer.
Вы можете начать отключать потоки и не беспокоиться о присоединении.
for (int i = 0; i < 2; i++) {
pthread_t tid;
pthread_create(&tid, NULL, routine, NULL);
pthread_detach(tid);
}
pthread_exit(0);
Или, альтернативно, вы можете иметь поток, который умирает, сообщать основному потоку, кто он, так что потоки соединяются в том порядке, в котором они выходили, а не в том порядке, в котором вы их создали.
void *routine(void *arg)
{
int *fds = (int *)arg;
pthread_t t = pthread_self();
usleep((rand()/(1.0 + RAND_MAX)) * 1000000);
write(fds[1], &t, sizeof(t));
}
int main()
{
int fds[2];
srand(time(0));
pipe(fds);
for (int i = 0; i < 2; i++) {
pthread_t tid;
pthread_create(&tid, NULL, routine, fds);
printf("created: %llu\n", (unsigned long long)tid);
}
for (int i = 0; i < 2; i++) {
pthread_t tid;
read(fds[0], &tid, sizeof(tid));
printf("joining: %llu\n", (unsigned long long)tid);
pthread_join(tid, 0);
}
pthread_exit(0);
}