来自 boost 的 udp 服务器不适用于多线程,但仅在主线程上工作
Udp server from boost not working on multithreading, but work only on the main thread
我得到了一个带有 boost::asio 的异步 udp 服务器 但问题是: 如果我在线程上启动它,服务器将无法工作 但是如果我在主线程上启动它(用服务阻止),它就可以工作了......
我尝试用叉子做,但不能工作
class Server {
private:
boost::asio::io_service _IO_service;
boost::shared_ptr<boost::asio::ip::udp::socket> _My_socket;
boost::asio::ip::udp::endpoint _His_endpoint;
boost::array<char, 1000> _My_Buffer;
private:
void Handle_send(const boost::system::error_code& error, size_t size, std::string msg) {
//do stuff
};
void start_send(std::string msg) {
_My_socket->async_send_to(boost::asio::buffer(msg), _His_endpoint,
boost::bind(&Server::Handle_send, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred, msg));
};
void Handle_receive(const boost::system::error_code& error, size_t size) {
//do stuff
};
void start_receive(void) {
_My_socket->async_receive_from(
boost::asio::buffer(_My_Buffer), _His_endpoint,
boost::bind(&Server::Handle_receive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
public:
Server(int port):
_IO_service(),
_My_socket(boost::make_shared<boost::asio::ip::udp::socket>(_IO_service,
boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port)))
{
start_receive();
};
void Launch() {
_IO_service.run();
};
};
目标是在后台调用服务器::启动。
首先,您在start_send
中有未定义的行为。
async_send_to
立即返回,因此当start_send
返回时,作为局部变量msg
将被销毁。调用async_send_to
时,必须确保在异步操作完成之前不会销毁msg
。文档中描述的内容 -
尽管可以根据需要复制缓冲区对象,但所有权 底层内存块由调用方保留,调用方必须保证它们在调用处理程序之前保持有效。
您可以通过多种方式解决它,最简单的方法是使用字符串作为数据成员(作为发送数据的缓冲区):
class Server {
//..
std::string _M_toSendBuffer;
//
void start_send(std::string msg) {
_M_toSend = msg; // store msg into buffer for sending
_My_socket->async_send_to(boost::asio::buffer(_M_toSend), _His_endpoint,
boost::bind(&Server::Handle_send, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
_M_toSend));
};
另一种解决方案是将msg
包装到智能指针中以延长其生命周期:
void Handle_send(const boost::system::error_code& error, size_t size,
boost::shared_ptr<std::string> msg) {
//do stuff
};
void start_send(std::string msg) {
boost::shared_ptr<std::string> msg2 = boost::make_shared<std::string>(msg); // [1]
_My_socket->async_send_to(boost::asio::buffer(*msg2), _His_endpoint,
boost::bind(&Server::Handle_send, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
msg2)); // [2]
};
在 [1] 行中,我们创建shared_ptr
它获取msg
内容,然后在 [2] 行中,当调用bind
时,shared_ptr
的引用计数器会增加,因此字符串生存期延长,并在调用处理程序后销毁。
关于您基于线程的不工作版本。您没有显示调用Launch
的代码,但也许您只是没有加入此线程?
Server s(3456);
boost::thread th(&Server::Launch,&s);
th.join(); // are you calling this line?
或者也许您的代码在 UB 中不起作用start_send
.
相关文章:
- C++为线程工作动态地分割例程
- 自 Windows 10 20H1 以来,具有单独线程的多个窗口停止工作
- 餐饮哲学家问题 - 只有 2 个线程工作
- 工作线程在执行太快后永久休眠
- 唤醒多个线程以在每个条件下工作一次
- Qt::D irectConnection在多线程环境中使用时如何工作?
- ZeroMQ 在使用 std::thread 创建工作线程时崩溃
- 工作线程一直在等待,condition_variable甚至调用了notify_all
- 使用 std::atomic 标志和 std::condition_variable 在工作线程上等待
- SIGABRT 和线程相关的异常,但在调试期间工作正常
- c++线程的安全性和时间效率:为什么有互斥检查的线程有时比没有它的线程工作得更快
- 在多线程工作负载上解释Gperftools的结果
- 我的线程工作不好,它给出了所有结果,最后没有一个接一个,GUI 在线程运行期间挂起?
- BOOST::线程工作线程同步,C++和OpenCV
- 线程工作不正常
- 提升线程工作线程对象在线程完成后的重用
- 线程问题,其中一个线程工作,但导致调用方法不返回
- 线程工作目录
- MFC主UI线程工作和模态对话框
- 用类对象提升线程工作器