提升 asio 和线程,如果我运行两个实例,我会获得 100% 的 cpu

Posted

技术标签:

【中文标题】提升 asio 和线程,如果我运行两个实例,我会获得 100% 的 cpu【英文标题】:Boost asio and thread, if i run two instances i get cpu at 100% 【发布时间】:2011-09-13 16:09:59 【问题描述】:

我创建了一个通过网络链接发送数据的控制台应用程序。我使用了 boost 库,包括线程和 asio 库;目前我在 Windows 下运行它。如果我运行单个应用程序,它可以完美运行,但如果我在两个不同的控制台上打开两个实例,CPU 负载会达到 100%,如果我关闭其中一个应用程序,它就会恢复正常。我只是使用了一个带有异步读写的简单套接字,以及带有条件变量和互斥锁的线程。处理这种情况时有什么特别的事情要做吗?我可以给你看一些代码,但我觉得没什么特别的:

socket->connect(tcp::endpoint(address::from_string(getAddress()),getPort()));

用于连接

socket->async_read_some(buffer(receiveData),bind(&NetworkLink::handle_response, this,placeholders::error,placeholders::bytes_transferred));

在handle_response 函数中用于异步读取。 对于我使用的线程

boost::unique_lock<boost::mutex> messages_lock(message_received_mutex);

在删除所有内容并从头开始一个简单的测试项目之前,我想知道在这种情况下是否需要特别注意。

【问题讨论】:

那么,您希望您支付的所有处理能力都被浪费掉吗?请解释为什么您认为这种行为不正确/不受欢迎。 请发布演示问题的完整代码。 你能用“async_read”而不是“async_read_some”来重新检查。这只是我的直觉。需要更多/完整的代码才能理解 @r-martinho-fernandes 为什么当软件什么都不做时我要让 CPU 始终处于 100% 状态?我的代码分布在很多类上,我会尝试做一个简单的例子并发布它。谢谢 PS:正如我所说,只有当我运行程序的两个实例时才会发生这种情况,只有一个它可以正常工作! 【参考方案1】:

好的,看来我已经找到了问题所在。首先,100% 的 CPU 使用率是因为每个实例都使用了 50% 的 CPU(我在双核 PC 上)。所以我运行了所有代码并发现了这一点。我的代码中有这个,在 NetworkLink::handle_response 函数中:

socket->async_read_some(
    boost::asio::buffer(receiveData),
    boost::bind(&NetworkLink::handle_response, this,
    boost::asio::placeholders::error,
    boost::asio::placeholders::bytes_transferred));
io_service.run();

我使用了 io_service.run();因为之前软件没有接收数据。现在我删除了这条线,我没有得到 50% 的 CPU 使用率,但是没有调用处理程序响应,所以我无法接收任何数据。有没有想过这个? 谢谢

PS:我创建了一个显示此问题的小应用程序:

#include <iostream>
#include <boost/asio.hpp>
#include "boost/thread.hpp"
#include "boost/thread/mutex.hpp"

#ifdef _WIN32
#include "Windows.h"
#endif

using namespace boost::asio::ip;
using namespace std;

std::vector<uint8_t> buf;
boost::asio::io_service io_service;
boost::asio::ip::tcp::socket mysocket(io_service);

int handle_response(const boost::system::error_code &err,
        size_t bytes_transferred)

    // cout << bytes_transferred << ' ';
    if (bytes_transferred > 0)
        cout << buf.data() << ' ';
    boost::asio::async_read(mysocket, boost::asio::buffer(buf),
            boost::asio::transfer_at_least(1), &handle_response);


int mythread()

    boost::asio::async_read(mysocket, boost::asio::buffer(buf),
            boost::asio::transfer_at_least(1), &handle_response);

    io_service.run();


int main()

    int m_nPort = 12345;

    buf.resize(100, '0');
    boost::condition_variable message_received_condition;
    boost::thread message_receiver_thread(&mythread);
    boost::mutex messages_mutex;

    tcp::endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"),
            m_nPort);

    boost::unique_lock<boost::mutex> messages_lock(messages_mutex);
    message_received_condition.notify_one();

    cout << "Waiting for connection..." << endl;

    Sleep(10000);
    mysocket.connect(endpoint);
    cout << "connection accepted" << endl;
    try
    
        while (true)
        
            boost::system::error_code ec;
            boost::asio::socket_base::bytes_readable command(true);
            mysocket.io_control(command);
            std::size_t bytes_readable = command.get();

            mysocket.async_read_some(boost::asio::buffer(buf),
                    &handle_response);

            io_service.run();
        
     catch (exception &e)
    
        cerr << e.what() << endl; //"The parameter is incorrect" exception
    

如果您从第 行删除注释 // cout

【讨论】:

似乎 boost::asio::transfer_at_least(1) 不起作用,因为在没有接收到数据时也会调用处理程序(即 bytes_transferred == 0),这是正常的吗行为?【参考方案2】:

您没有检查错误。如果出现故障,您仍然继续阅读,这可能会立即回发一个失败的完成,无穷无尽。

【讨论】:

我更改了代码并添加了 1 毫秒的睡眠,如果没有读取任何内容,我的 CPU 负载非常低,这是您的意思吗?

以上是关于提升 asio 和线程,如果我运行两个实例,我会获得 100% 的 cpu的主要内容,如果未能解决你的问题,请参考以下文章

两个线程c ++之间的boost asio通信

提升 Asio 单线程性能

提升 asio 绑定:错误的文件描述符

使用 asio 提升线程池:线程随机不执行

C++ 提升 asio 多线程

C++ 线程与 boost asio