【发布时间】:2011-11-13 20:12:47
【问题描述】:
(这是我原来问题的简化版)
我有几个线程写入 boost asio 套接字。这似乎工作得很好,没有问题。
文档说共享套接字不是线程安全的(here,在底部)所以我想知道是否应该用互斥锁或其他东西保护套接字。
question 坚持认为保护是必要的,但没有给出如何保护的建议。
我最初问题的所有答案也坚持认为我所做的事情很危险,并且大多数人都敦促我用 async_writes 或更复杂的东西替换我的写入。但是,我不愿意这样做,因为这会使已经运行的代码复杂化,并且没有一个回答者让我相信他们知道他们在说什么 - 他们似乎已经阅读了与我相同的文档并且正在猜测,就像我一样是。
所以,我编写了一个简单的程序来对从两个线程写入共享套接字进行压力测试。
这里是服务器,它只是简单地写出它从客户端接收到的任何内容
int main()
{
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 3001));
tcp::socket socket(io_service);
acceptor.accept(socket);
for (;;)
{
char mybuffer[1256];
int len = socket.read_some(boost::asio::buffer(mybuffer,1256));
mybuffer[len] = '\0';
std::cout << mybuffer;
std::cout.flush();
}
return 0;
}
这里是客户端,它创建两个线程以尽可能快地写入共享套接字
boost::asio::ip::tcp::socket * psocket;
void speaker1()
{
string msg("speaker1: hello, server, how are you running?\n");
for( int k = 0; k < 1000; k++ ) {
boost::asio::write(
*psocket,boost::asio::buffer(msg,msg.length()));
}
}
void speaker2()
{
string msg("speaker2: hello, server, how are you running?\n");
for( int k = 0; k < 1000; k++ ) {
boost::asio::write(
*psocket,boost::asio::buffer(msg,msg.length()));
}
}
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
// connect to server
tcp::resolver resolver(io_service);
tcp::resolver::query query("localhost", "3001");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
psocket = new tcp::socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
psocket->close();
psocket->connect(*endpoint_iterator++, error);
}
boost::thread t1( speaker1 );
boost::thread t2( speaker2 );
Sleep(50000);
}
这行得通!完美,据我所知。客户端不会崩溃。消息到达服务器时不会出现乱码。它们通常交替到达,每个线程一个。有时一个线程在另一个线程之前收到两三条消息,但我认为这不是问题,只要没有乱码并且所有消息都到达。
我的结论:从理论上讲,套接字可能不是线程安全的,但是很难让它失败,所以我不会担心它。
【问题讨论】:
-
将 io_service::post() 与调用 write() 的处理程序一起使用几乎没有价值。你太复杂了,使用 async_write()。
-
从 ASIO 的角度来看,您的实施没有意义。这种代码风格不需要 asio。
-
为什么你认为你需要多个线程?
标签: c++ boost boost-asio