c++中的异步函数

Asynchronous Function in C++

本文关键字:函数 异步 c++      更新时间:2023-10-16

我有一个类对象,作为一个服务器。它接收来自任何地方的请求,并将请求推送到它的请求队列(Producer)中。现在有一个消费者线程正在运行,它从请求队列中弹出请求,并根据请求调用适当的类方法来提供请求。现在,从队列中消费请求和启动适当的函数将以同步的方式执行。我想要的是消费者线程从队列中弹出一个请求,并以异步方式启动适当的函数,以便消费者可以立即从队列中弹出下一个请求。

我尝试过的一个解决方案是,消费者从队列中弹出一个请求,并创建一个boost::thread,并在一个新线程中启动适当的函数。我在std::vector中保存了线程指针,也尝试了boost::thread_group。到目前为止一切顺利。但是这个解决方案有一个问题。

一旦我提供了超过150个请求,就会有更多的150个线程,之后pthread不会创建新线程,给出错误"pthread_create: Resource temporarily unavailable",我认为这意味着当前进程的堆栈已经耗尽,因此无法创建新线程。

问题#1我的请求处理程序不包含while (1),那些只是在做一些工作和退出,根本不等待任何东西,这就是为什么我期待我的初始线程已经完成了它们的处理并从线程处理程序函数退出。考虑到这一点,如果线程已经完成了处理并退出,它不应该从堆栈中清理它的东西吗?

这个问题的一个解决方案是我可以设置线程的堆栈大小,但是在1000个线程之后仍然会引发这个错误。

所以我的要求是我必须在一段时间后清理完成的线程(即,当线程指针向量超过100或每1分钟或类似的东西之后)。

问题#2除了启动新线程,我上面提到的其他异步函数调用机制是什么,我应该尝试。boost::function + boost::bind是不是异步的?这是解决我提到的情况的好办法吗?假设我的系统365天24小时在线,每天接收1000个请求。


Update # 1 所以我在设计中发现了一个问题。我在我的问题#1中提到,我的请求处理程序只包含我发现不正确的普通调用。它从服务器同步下载文件,这本质上是一个阻塞操作。我应该异步下载文件。

如果请求处理程序没有执行任何阻塞操作,那么创建底层系统无法并发处理的线程是没有意义的。

因此,正如Alex提到的,有多个消费者线程(我认为5个就足够了)从队列中弹出一个请求,并有一个异步文件下载将解决我的问题。

一种解决方案是使用多个消费者线程,每个消费者线程从队列中弹出一个工作项并同步处理它。它使您能够管理并发性(避免过度订阅),同时仍然一次处理多个项目。您还消除了在每个项目上启动新线程的开销,我认为这是您的瓶颈之一。

你应该确保你的队列是为多个消费者设计的。

从来没有使用过这个实现,但是一个线程池可能会有帮助。

您已经使用Boost并下载文件。所以使用Boost是很自然的。Asio用于网络和所有其他多线程/异步相关的东西,如中央调度程序。

首先,我建议创建一个线程池,并在它们上面运行Asio调度程序:如下所示。使用Asio异步网络下载文件:示例如下。当一个文件被下载时,只处理它。

这种方法是相当可扩展的,你不会担心异步网络或多线程同步(相当棘手的东西)。提振。Asio提供了一个很好的例子来完成这个任务。