Boost 异步写入延迟后未调用的回调
睡眠一秒钟后,我对Boost 异步写入延迟后未调用的回调,boost,tcp,callback,boost-asio,asyncsocket,Boost,Tcp,Callback,Boost Asio,Asyncsocket,睡眠一秒钟后,我对async\u write\u some的回调没有被调用。如果每次写入都启动io\u服务worker线程,为什么不调用回调 标题 boost::system::error_code error_1; boost::shared_ptr <boost::asio::io_service> io_service_1; boost::shared_ptr <boost::asio::ip::tcp::socket> socket_1; 这很奇怪,原因有很多
async\u write\u some
的回调没有被调用。如果每次写入都启动io\u服务
worker线程,为什么不调用回调
标题
boost::system::error_code error_1;
boost::shared_ptr <boost::asio::io_service> io_service_1;
boost::shared_ptr <boost::asio::ip::tcp::socket> socket_1;
这很奇怪,原因有很多
- 您不应该为每个操作“运行”io_服务。相反,在发布操作时稳定地运行它们。可以选择使用
来防止运行返回io\u service::work
- 您不应该(必须)为每个操作创建线程。如果有什么不同的话,那就是同步问题的秘诀()
- 在返回后再次运行
io\u服务时(无错误),您应根据文档()首先调用
reset()
- 您破坏了一个未分离的线程——可能是在它完成之前。如果您使用了
,这甚至会导致程序立即异常终止。不连接未分离的线程是一种不好的做法(我要补充的是,在线程终止时不显式同步就使用分离的线程是不可靠的)。看std::thread
- 使用诸如
之类的名称(只需将其命名为socket\u 1
,并用描述性名称实例化另一个对象以包含另一个socket\u
)。我不确定,但这个问题确实让人怀疑这些甚至可能是全局变量。(我希望不是这样)socket\u
- 抛出原始整数,真的吗
- 破坏
,而从不检查工作线程是否已完成,这可能会导致数据争用io_服务
- 详情如下:
传递对超出范围的参数
数据的引用。当异步操作完成时,它将是一个悬空引用
- 这里存在一些明显的复制/粘贴问题:
if (socket_1.get() == NULL || !socket_1->is_open()) { WARNING << "serial_port_1 is not open"; return; }
感谢sehe的帮助和祈祷,我的问题现在已经解决了
中的这一行:open\u eth\u socket
现在是:boost::thread t(boost::bind(&boost::asio::io_service::run, *&io_service_1));
boost::shared_ptr <boost::thread> io_service_1_thread; // in header if (io_service_1_thread.get()) io_service_1_thread->interrupt(); io_service_1_thread.reset(new boost::thread (boost::bind(ð_socket::run_io_service_1, this)));
我增加了这个功能:boost::共享\u ptr io\u服务\u 1\u线程;//在标题中 如果(io_服务线程.get())io_服务线程->中断(); io_服务_1_线程.reset(新的boost::thread(boost::bind(ð_socket::run_io_服务_1,this));
void eth_socket::run_io_service_1 (void) { while (true) // work forever { boost::asio::io_service::work work(*io_service_1); io_service_1->run(); io_service_1->reset(); // not sure if this will cause problems yet INFO << "io_service_1 run complete"; boost::this_thread::sleep (boost::posix_time::milliseconds (100)); } return; }
void eth_socket::运行_io_服务_1(void) { while(true)//永远工作 { boost::asio::io_服务::工作(*io_服务_1); io_服务_1->run(); io_服务_1->reset();//不确定这是否会导致问题
信息说明当
与之前的读取重叠时,这就留下了数据争用的问题。稍后我将链接到常见的解决方案。谢谢。我想我的问题是write\u data
io\u服务和线程。所以
线程总是在运行?在回调中我应该有\u work
并在我连接后启动io\u 1->reset()
工作线程?我认为工作线程在回调上没有工作,因此每次写入时我都需要启动它…请阅读示例代码/我没有无故编写示例。如果您错过了,可能需要额外的后台链接:(它指的是第一个子弹)哦,我以前没有看到过,但是io_服务
肯定是错的。这是一个重复。你可能(毫无用处地)指的是*&io\u service\u 1
。但是和*io\u service\u
支持boost::bind
很好,直接-让它更安全)共享的\u ptr
boost::thread t(boost::bind(&boost::asio::io_service::run, *&io_service_1));
_sock.async_write_some( ba::buffer(data.c_str(), data.size()),
if (socket_1.get() == NULL || !socket_1->is_open()) { WARNING << "serial_port_1 is not open"; return; }
#include <boost/asio.hpp> #include <boost/thread.hpp> #include <iostream> namespace ba = boost::asio; using ba::ip::tcp; using boost::system::error_code; #define ERROR std::cerr #define WARNING std::cerr #define INFO std::cerr struct eth_socket { ~eth_socket() { _work.reset(); if (_worker.joinable()) _worker.join(); // wait } void open(std::string address); void write_data(std::string data); private: void connected(error_code error) { if (error) ERROR << "Connect failed: " << error << "\n"; else INFO << "Connected to " << _sock.remote_endpoint() << "\n"; } void written(error_code error, size_t bytes_transferred); private: ba::io_service _svc; boost::optional<ba::io_service::work> _work{ _svc }; boost::thread _worker{ [this] { _svc.run(); } }; std::string _data; unsigned short _port = 6767; tcp::socket _sock{ _svc }; }; void eth_socket::open(std::string address) { tcp::endpoint remote_endpoint(ba::ip::address::from_string(address), _port); _sock.async_connect(remote_endpoint, boost::bind(ð_socket::connected, this, _1)); } void eth_socket::write_data(std::string data) { _data = data; _sock.async_write_some(ba::buffer(_data), boost::bind(ð_socket::written, this, _1, _2)); } void eth_socket::written(error_code error, size_t bytes_transferred) { INFO << "data written to " << _sock.remote_endpoint() << " " << error.message() << ";" << "bytes_transferred = " << bytes_transferred << "\n"; } int main() { { eth_socket s; s.open("127.0.0.1"); s.write_data("Hello"); // callback called s.write_data("Hello"); // callback called s.write_data("Hello"); // callback called boost::this_thread::sleep_for(boost::chrono::seconds(1)); s.write_data("Hello"); // callback not called after sleep } // orderly worker thread join here }
boost::thread t(boost::bind(&boost::asio::io_service::run, *&io_service_1));
boost::shared_ptr <boost::thread> io_service_1_thread; // in header if (io_service_1_thread.get()) io_service_1_thread->interrupt(); io_service_1_thread.reset(new boost::thread (boost::bind(ð_socket::run_io_service_1, this)));
void eth_socket::run_io_service_1 (void) { while (true) // work forever { boost::asio::io_service::work work(*io_service_1); io_service_1->run(); io_service_1->reset(); // not sure if this will cause problems yet INFO << "io_service_1 run complete"; boost::this_thread::sleep (boost::posix_time::milliseconds (100)); } return; }