C++ boost::asio异步条件

C++ boost::asio异步条件,c++,multithreading,boost,boost-asio,C++,Multithreading,Boost,Boost Asio,其思想是能够用boost::asio和线程池来替换多线程代码,以解决消费者/生产者问题。目前,每个消费者线程都在等待一个boost::condition\u变量——当生产者向队列添加内容时,它调用notify\u one/notify\u all通知所有消费者。现在,当您(潜在)拥有1k+消费者时会发生什么?线程无法缩放 我决定使用boost::asio,但后来我发现它没有条件变量。然后async\u condition\u variable诞生了: class async_condition_

其思想是能够用boost::asio和线程池来替换多线程代码,以解决消费者/生产者问题。目前,每个消费者线程都在等待一个
boost::condition\u变量
——当生产者向队列添加内容时,它调用
notify\u one
/
notify\u all
通知所有消费者。现在,当您(潜在)拥有1k+消费者时会发生什么?线程无法缩放

我决定使用
boost::asio
,但后来我发现它没有条件变量。然后
async\u condition\u variable
诞生了:

class async_condition_variable
{
private:
    boost::asio::io_service& service_;
    typedef boost::function<void ()> async_handler;
    std::queue<async_handler> waiters_;

public:
    async_condition_variable(boost::asio::io_service& service) : service_(service)
    {
    }

    void async_wait(async_handler handler)
    {
        waiters_.push(handler);
    }

    void notify_one()
    {
        service_.post(waiters_.front());
        waiters_.pop();
    }

    void notify_all()
    {
        while (!waiters_.empty()) {
            notify_one();
        }
    }
};
类异步条件变量
{
私人:
boost::asio::io_服务&服务u;
typedef boost::函数异步_处理程序;
标准:排队等候者;
公众:
异步条件变量(boost::asio::io\u服务和服务):服务(服务)
{
}
void async\u wait(异步处理程序)
{
服务员推(服务员);
}
作废通知单()
{
服务站(服务员站前());
侍者(流行音乐);
}
void notify_all()
{
而(!waiters.empty()){
通知某人;
}
}
};
基本上,每个使用者都会调用
async\u condition\u变量::wait(…)
。然后,生产者最终将调用
async\u条件变量::notify\u one()
async\u条件变量::notify\u all()
。将调用每个使用者的句柄,并对该条件执行操作,或者再次调用
async\u condition\u变量::wait(…)
。这是可行的还是我疯了?考虑到这将在线程池上运行,应该执行什么类型的锁定(互斥锁)


附言:是的,这更多的是一个RFC(征求意见),而不是一个问题:)

列出事件发生时需要做的事情。有一个函数可以向列表中添加某些内容,还有一个函数可以从列表中删除某些内容。然后,当事件发生时,在现在需要完成的作业列表上有一个线程池。您不需要专门等待事件的线程。

你不需要让线程等待任何东西。当他们没有任何工作要做时,他们会自己做。这些看起来像是您想要做的事情的示例已将每个项目的工作发布到io_服务

以下代码的灵感来自。事实上,它让我明白了你可以用它做很多事情

我相信这并不完美,但我认为它给出了总体思路。我希望这有帮助

代码
#包括
#包括
#包括
#包括
类服务器处理器
{
受保护的:
无效处理工作1(工作对象1*工作)
{
//执行任务1的代码在这里
}
无效处理作业2(作业对象2*作业)
{
//执行任务2的代码在这里
}
boost::线程\u组工作线程\u;
boost::asio::io_服务io_服务;
//这用于防止io_服务耗尽工作并很快退出。
boost::共享工作;
公众:
无效开始(int numberOfThreads)
{
boost::shared_ptr myWork(新的boost::asio::io_服务::work(io_服务));
工作=我的工作;
对于(int x=0;xstd::cout使用boost::signals2怎么样

它是boost::signals的线程安全衍生产品,允许您的客户端订阅要发出的信号的回调


然后,当信号在io_服务调度的作业中异步发出时,所有注册的回调都将执行(在发出信号的同一线程上)。

用例是什么?当发生某件事情时,您需要做1000件不同的事情吗?如果是这样,这完全是错误的做法。(一个线程池应该在处理现在需要完成的1000个作业。)我有一个(可能很大)需要能够从中央服务器接收任务的一组客户端。这些客户端中的很大一部分将位于防火墙后面,因此我们的想法是保持客户端-服务器连接始终打开。当外部控制器发布新任务时,服务器需要此“异步条件变量”将任务分派给给定的客户端。我有同样的问题。想象一下为APNS实现一个服务器。在APNS中,除非出现错误,否则推送消息不会得到响应。此外,您还希望保持套接字打开以推送更多消息。因此,您有这个连接池,他们需要从该池中获取下一条消息。当然,您可以使用条件_变量来实现这一点。但是等待一个条件变量将挂起连接线程,因此,除非使用wait with timeout创建一个近乎繁忙的旋转状态,否则异步读取无法正常工作。下面是我目前的结果(工作正常):boost::asio::deadline\u timer也可以做同样的事情。那么如何调用从列表中删除某些内容的函数呢?请注意,我将boost::asio与线程池一起使用,但池中的线程数也可能是一个。@brunonery:我不确定您的确切要求,但该函数将是cla的成员函数它将获取保护列表的锁,然后从列表中删除该项。(列表
#include <iostream>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
class ServerProcessor
{
protected:
    void handleWork1(WorkObject1* work)
    {
        //The code to do task 1 goes in here
    }
    void handleWork2(WorkObject2* work)
    {
        //The code to do task 2 goes in here
    }

    boost::thread_group worker_threads_;

    boost::asio::io_service io_service_;
    //This is used to keep io_service from running out of work and exiting to soon.
    boost::shared_ptr<boost::asio::io_service::work> work_;


public:
    void start(int numberOfThreads)
    {
        boost::shared_ptr<boost::asio::io_service::work> myWork(new boost::asio::io_service::work(io_service_));
        work_=myWork;

        for (int x=0; x < numberOfThreads; ++x)
            worker_threads_.create_thread( boost::bind( &ServerProcessor::threadAction, this ) );

    }

    void doWork1(WorkObject1* work)
    {
        io_service_.post(boost::bind(&ServerProcessor::handleWork1, this, work));
    }

    void doWork2(WorkObject2* work)
    {
        io_service_.post(boost::bind(&ServerProcessor::handleWork2, this, work));
    }


    void threadAction()
    {
        io_service_.run();
    }

    void stop()
    {
        work_.reset();
        io_service_.stop();
        worker_threads_.join_all();
    }

};

int main()
{
    ServerProcessor s;

    std::string input;
    std::cout<<"Press f to stop"<<std::endl;

    s.start(8);

    std::cin>>input;

    s.stop();

    return 0;
}