(это упрощенная версия моего оригинального вопроса)
У меня есть несколько потоков, которые пишут в розетке ASIO. Кажется, это очень хорошо работает, без проблем.
Документация говорит, что общий сокет не безопасен в потоке ( здесь , путь вниз внизу), поэтому мне интересно, если я должен защитить розетку с Mutex или что-то.
Это вопрос настаивает на том, что защита необходима, но не дает совета о том, как это сделать.
Все ответы на мой первоначальный вопрос также настаивали на том, что я делал опасным, и наиболее призвал меня заменить мои пишеты с 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);
}
Это работает! Отлично, насколько я могу сказать. Клиент не сбивается. Сообщения прибывают на сервер без галочек. Они обычно поступают попеременно, один из каждой нити. Иногда одна нить получила два или три сообщения до других, но я не думаю, что это проблема, пока нет гарка, и все сообщения прибывают.
Мой вывод: розетка может не быть в безопасности в одном теоретическом смысле, но так сложно сделать, что я не собираюсь беспокоиться об этом.