简体   繁体   English

用多核增强协程

[英]boost coroutine with multi core

My tcp server is based on this boost coroutine server example . 我的tcp服务器基于此boost协程服务器示例

There're lots of request per second, the server have two cores but only one is used, it never goes over than 50% cpu in task manager's performance tab, and one core is always free: 每秒有很多请求,服务器有两个内核,但仅使用一个,在任务管理器的“性能”选项卡中,CPU永远不会超过50%cpu,并且一个内核始终是空闲的: 在此处输入图片说明

How to make boost::coroutine work with multiple cores? 如何使boost :: coroutine与多个内核一起工作?

I just came up a solution that add a thread_pool : 我只是想出一个添加thread_pool的解决方案:

#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/spawn.hpp>
#include "thread_pool.h"
#include <iostream>

using boost::asio::ip::tcp;

class session : public std::enable_shared_from_this<session>
{
public:
  explicit session(tcp::socket socket) { }

  void go()
  {
      std::cout << "dead loop" << std::endl;
      while(1) {} // causes 100% cpu usage, just for test
  }
};

int main()
{
  try
  {

    boost::asio::io_service io_service;

    thread_pool pool(1000); // maximum 1000 threads

    boost::asio::spawn(io_service,
        [&](boost::asio::yield_context yield)
        {
          tcp::acceptor acceptor(io_service,
            tcp::endpoint(tcp::v4(), 80));

          for (;;)
          {
            boost::system::error_code ec;
            tcp::socket socket(io_service);
            acceptor.async_accept(socket, yield[ec]);
            if (!ec) {
                pool.enqueue([&] { // add this to pool
                    std::make_shared<session>(std::move(socket))->go();
                });
            }
          }
        });

    io_service.run();
  }
  catch (std::exception& e)
  {}

  return 0;
}

Now the code seems running with 100% cpu after telnet 127.0.0.1 80 twice. 现在代码似乎在telnet 127.0.0.1 80之后两次以100%cpu运行。

But what's the common way of using coroutine with multi cores? 但是,将协程用于多核的常见方法是什么?

One thread only runs on one core, so you have to create multiple threads with separate coroutines. 一个线程仅在一个内核上运行,因此您必须使用独立的协程创建多个线程。 asio already contains some thread management support, so you mostly have to start some threads: asio已经包含一些线程管理支持,因此您通常必须启动一些线程:

int main() {
  std::vector<std::thread> pool;
  try {
    boost::asio::io_service io_service;
    {
      for(auto threadCount = std::thread::hardware_concurrency();
          threadCount;--threadCount)
        pool.emplace_back([](auto io_s) {return io_s->run(); }, &io_service);
    }

    // Normal code
  } catch(std::exception &e) {}
  for(auto &thread : pool) 
    thread.join();
  return 0;
}

The important thing is to run io_service.run() on every thread. 重要的是在每个线程上运行io_service.run() Then, after .async_accept , you can call 然后,在.async_accept之后,您可以调用

io_service.post(&session::go, std::make_shared<session>(std::move(socket)))

to run the session somewhere in the pool. 在池中某处运行会话。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM