2011-09-13 33 views
0

我创建了一个控制台应用程序,在网络链接上发送数据。我使用boost库,线程和asio;目前我在Windows下运行它。如果我运行一个应用程序,它可以很好地工作,但是如果我在两个不同的控制台上打开两个实例,则CPU负载会达到100%,如果关闭其中一个应用程序,它将恢复正常。我只是使用了一个简单的套接字来进行异步读写,并且使用了条件变量和互斥体的线程。处理这种情况时有什么特别的事情要做?我可以告诉你一些代码,但我认为这是没有什么特别的:提升asio和线程,如果我运行两个实例,我得到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); 

删除一切,从头开始一个简单的测试项目,我想知道是否有在这种情况下应采取的任何特殊照顾了。

+0

那么,你想要你付出的所有处理能力去浪费吗?请解释您为什么认为这种行为不正确/需要。 –

+2

请发布完整的代码来演示问题。 –

+0

你可以通过使用“async_read”而不是“async_read_some”来重新检查吗?它只是我的直觉。需要更多/完整的代码来理解 – Arunmu

回答

0

好吧,看来我已经找到了问题。首先,100%的CPU使用率是因为每个实例都使用了50%的CPU(我在双核PC上)。所以我跑遍了所有的代码并发现了这一点。我在我的代码了这一点,网络链接:: 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 < < bytes_transferred < <“删除注释; 在句柄响应函数中,你会得到较低的CPU使用率,我猜是因为延迟写入屏幕。

+0

似乎boost :: asio :: transfer_at_least(1)不起作用,因为在没有收到数据(即bytes_transferred == 0)时也会调用处理程序,这是否是正常行为? – cpl

0

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

+0

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