我需要提示如何在C / C ++中实现异步函数调用(或者用于windows和/或linux的框架/ API调用的名称)
用例如下:父线程调用函数。该函数创建一个子线程并返回,因此调用是非阻塞的,父线程可以继续做一些工作。
例如,获取结果的pthread_join不合适,因此必须将结果存储在堆中,并且必须通知父级。我想要的是像父线程中的回调函数,它将在子线程准备就绪后执行。
这是令人惊讶的,但我在谷歌找不到一个例子。
感谢您的帮助
答案 0 :(得分:8)
C ++ 0x为此提供std::async
。这是现有的implementation,discussion和Wikipedia。
答案 1 :(得分:7)
不是使用不同的框架,并注意到你在问题中提到pthread_join()
,你仍然可以用POSIX C达到预期的效果。为此,你可以使用信号来确认一个并行的线程任务完成。在此方法中,您为用户定义的信号(例如SIGUSR1
)安装信号处理程序,创建一组具有不同任务的工作线程,并让它们在父项完成时发出信号。
以下程序说明了这种尝试。在该示例中,我使用SIGUSR1
通知父线程完成某些处理。父线程一直忙着做一些I / O,直到子线程中断为止。请注意,为清楚起见,没有放置任何类型的错误处理代码。
#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定义的完全不同。如果您担心可移植性或合规性,则应进一步修改上述解决方案。
答案 2 :(得分:4)
我建议您查看http://www.threadingbuildingblocks.org/。
Task类(http://cache-www.intel.com/cd/00/00/30/11/301114_301114.pdf#page=95)可能是一个起点。
答案 3 :(得分:3)
我相信这可以很好地完成工作。将函数调用作为新线程旋转,只是不要加入它。无论如何我会相信它会照顾到它。
您可以对其进行设置,以便孩子在完成使用Boost.Signals时向父母发送信号。该信号将链接到父母的回调函数。
答案 4 :(得分:1)
使用boost :: thread作为标准的跨平台解决方案。如果你需要更多的东西,那就是英特尔的线程构建模块。
答案 5 :(得分:0)
您必须设置某种基础结构来通知调用者工作已完成。这可以使用Observer模式类型完成。也可以使用消息类型基础结构。
真正的问题是你的父母在等待时会做什么。你想让它进行民意调查吗?或者得到通知?
答案 6 :(得分:0)
使用Qt框架和Thread类或Qt Concurrency框架。
连接到QThread :: finished()或QFutureWatcher :: finished()信号,以便在工作完成时得到通知。
答案 7 :(得分:0)
我在你对Starkey的回复中看到主线程是一个UI线程。
我使用了几种不同的GUI工具包,所有这些工具包都允许您从不同的线程发布消息。因此,工作线程在完成后发布GUI消息,然后处理程序将在主线程中运行。
在Windows中,使用PostMessage
。
在Linux中,使用XtAppAddSignal
and XtNoticeSignal