Вместо того, чтобы использовать разные фреймворки и отмечая, что вы упомянули pthread_join()
в своем вопросе, вы все равно можете достичь желаемого эффекта с помощью POSIX C. Для этого вы можете использовать сигналы для подтверждения потока выполнения параллельной задачи , В этом методе вы устанавливаете обработчик сигнала для определяемого пользователем сигнала (например, SIGUSR1
), создаете набор рабочих потоков с различными задачами и позволяете им сигнализировать родителю, когда они завершены.
Следующая программа иллюстрирует попытку. В этом примере я использую SIGUSR1
, чтобы сообщить родительскому потоку о завершении некоторой обработки. Родительский поток остается занятым, выполняя некоторые операции ввода-вывода, пока его не прервет дочерний поток. Обратите внимание, что для ясности, никакой код обработки ошибок не был помещен.
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* Variable to hold the value of some calculation. */
int value = 0;
/* Variable used by the parent thread to inform itself of task completion. */
volatile sig_atomic_t value_received = 0;
/* Signal handler to handle the SIGUSR1 signal (the signal used to acknowledge the parent of task completion). */
void handler(int signum) {
value_received = 1;
}
/* Working thread routine. First parameter is a pthread_t (cast to void*) identifying the parent. */
void *thread(void *parent) {
/* Do something lengthy here, such as a long calculation. */
value = 1;
sleep(5); /* Simulate lengthy operation. */
/* After processing, inform the parent thread that we have ended. */
pthread_kill((pthread_t)parent, SIGUSR1);
return NULL;
}
int main(void) {
struct sigaction action;
pthread_t child;
/* Install signal handler to receive the child thread notification. */
action.sa_handler = handler;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
sigaction(SIGUSR1, &action, NULL);
/* Create child thread that will perform some task. */
pthread_create(&child, NULL, thread, (void*)pthread_self());
/* Detach thread from execution. No need to join the thread later. */
pthread_detach(child);
/* Do some other processing while the ongoing task is running in parallel. */
while (!value_received) {
char buffer[0x100];
/* Echo some input until something happens. */
if (!fgets(buffer, sizeof buffer, stdin))
break;
printf("You typed: %s", buffer);
}
/* Something happened (signal received or EOF in stdin). In the latter, just sleep a little while. */
if (feof(stdin))
while (!value_received)
sleep(1);
/* At this point, child thread has already ended the execution. */
printf("Value received: %i\n", value);
return EXIT_SUCCESS;
}
В примере используется реализация сигналов LinuxThreads, которая сильно отличается от того, что определяет POSIX. Если вы обеспокоены переносимостью или совместимостью, приведенное выше решение следует дополнительно пересмотреть.