увеличить сопрограмму с многоядерным

Мой TCP-сервер основан на этом Пример сервера Boost Coroutine.

Количество запросов в секунду велико, сервер имеет два ядра, но используется только одно, он никогда не превышает 50% процессорного времени на вкладке производительности диспетчера задач, и одно ядро ​​всегда свободно:
введите описание изображения здесь

Как заставить boost :: coroutine работать с несколькими ядрами?

Я просто придумал решение, которое добавляет 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;
}

Теперь код работает со 100% процессором после телнет 127.0.0.1 80 дважды.

Но каков общий способ использования сопрограммы с многоядерными процессорами?

0

Решение

Один поток работает только на одном ядре, поэтому вам нужно создать несколько потоков с отдельными сопрограммами. В 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;
}

Важно бежать io_service.run() на каждом потоке. Затем после .async_accept, ты можешь позвонить

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

запустить сеанс где-нибудь в бассейне.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]