BOOST_LOG_SEV 在创建线程后损坏 async_read_some
BOOST_LOG_SEV corrupts async_read_some after creating a thread
所以我在练习 boost 库时遇到了一些问题。我的应用程序使用 asio::serial_port,我决定添加一些日志功能。问题来了。
当我为 asio::io_service
创建线程时
boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service_));
然后尝试用
记录一些东西
BOOST_LOG_SEV(MBLog::get(), logging::trivial::trace) << "something to trace;"
在调用
之前
port_->async_read_some(
boost::asio::buffer(read_buf_raw_, SERIAL_PORT_READ_BUF_SIZE),
boost::bind(
&SerialPort::on_receive_,
this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
然后处理程序 on_receive_
永远不会被调用(端口仍然可以用 write_some
thow 写一些东西)。当记录宏被注释掉或在执行 async_read_some
后完成时,它会神奇地工作。我想知道这背后的魔力是什么,或者从哪里开始寻找答案?也许你们中的一些人已经知道这个问题然后请分享。其他有用信息:
我正在使用 MSVC2017.
提升日志初始化
Logger.h
#define _HAS_AUTO_PTR_ETC 1
#include <boost/log/trivial.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
namespace logging = boost::log;
namespace src = boost::log::sources;
namespace sinks = boost::log::sinks;
namespace keywords = boost::log::keywords;
namespace attrs = boost::log::attributes;
namespace expr = boost::log::expressions;
BOOST_LOG_GLOBAL_LOGGER(MBLog, src::severity_logger_mt<logging::trivial::severity_level>)
Logger.cpp
#include "Logger.h"
#include <boost/log/support/date_time.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
void full_detail_formatter(logging::record_view const& rec, logging::formatting_ostream& strm);
void normal_formatter(logging::record_view const& rec, logging::formatting_ostream& strm);
BOOST_LOG_GLOBAL_LOGGER_INIT(MBLog, src::severity_logger_mt<logging::trivial::severity_level>)
{
src::severity_logger_mt<logging::trivial::severity_level> lg;
logging::add_common_attributes();
auto file_sink = logging::add_file_log(
keywords::file_name = "./logs/L%Y-%m-%d_%3N.log", // one file per date and execution
keywords::rotation_size = 5 * 1024 * 1024, // rotate after 5MB
keywords::target = "./logs",
keywords::min_free_space = 30 * 1024 * 1024,
keywords::auto_flush = true,
keywords::scan_method = boost::log::sinks::file::scan_matching
);
file_sink->set_formatter(&full_detail_formatter);
file_sink->set_filter(
logging::trivial::severity >= logging::trivial::trace
);
auto console_sink = logging::add_console_log(std::clog);
console_sink->set_formatter(&full_detail_formatter);
console_sink->set_filter(
logging::trivial::severity >= logging::trivial::trace
);
logging::core::get()->set_filter(
logging::trivial::severity >= logging::trivial::trace
);
return lg;
}
编辑
似乎有人已经通过在执行 async_read_some
后为 asio::io_service::run
创建线程解决了这个问题
Seems like someone already solved this problem here by creating thread for asio::io_service::run after execution of async_read_some
是的。否则 run()
可能会在任何作品注册之前完成。
它的文档在这里:http://www.boost.org/doc/libs/1_65_0/doc/html/boost_asio/reference/io_service/run/overload1.html
The run() function blocks until all work has finished and there are no more handlers to be dispatched, or until the io_service has been stopped.
可以找到更多解释:
- Confused when boost::asio::io_service run method blocks/unblocks
考虑使用 io_service::work
保留服务:boost asio post not working , io_service::run exits right after post
所以我在练习 boost 库时遇到了一些问题。我的应用程序使用 asio::serial_port,我决定添加一些日志功能。问题来了。
当我为 asio::io_service
创建线程时boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service_));
然后尝试用
记录一些东西BOOST_LOG_SEV(MBLog::get(), logging::trivial::trace) << "something to trace;"
在调用
之前port_->async_read_some(
boost::asio::buffer(read_buf_raw_, SERIAL_PORT_READ_BUF_SIZE),
boost::bind(
&SerialPort::on_receive_,
this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
然后处理程序 on_receive_
永远不会被调用(端口仍然可以用 write_some
thow 写一些东西)。当记录宏被注释掉或在执行 async_read_some
后完成时,它会神奇地工作。我想知道这背后的魔力是什么,或者从哪里开始寻找答案?也许你们中的一些人已经知道这个问题然后请分享。其他有用信息:
我正在使用 MSVC2017.
提升日志初始化
Logger.h
#define _HAS_AUTO_PTR_ETC 1
#include <boost/log/trivial.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
namespace logging = boost::log;
namespace src = boost::log::sources;
namespace sinks = boost::log::sinks;
namespace keywords = boost::log::keywords;
namespace attrs = boost::log::attributes;
namespace expr = boost::log::expressions;
BOOST_LOG_GLOBAL_LOGGER(MBLog, src::severity_logger_mt<logging::trivial::severity_level>)
Logger.cpp
#include "Logger.h"
#include <boost/log/support/date_time.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
void full_detail_formatter(logging::record_view const& rec, logging::formatting_ostream& strm);
void normal_formatter(logging::record_view const& rec, logging::formatting_ostream& strm);
BOOST_LOG_GLOBAL_LOGGER_INIT(MBLog, src::severity_logger_mt<logging::trivial::severity_level>)
{
src::severity_logger_mt<logging::trivial::severity_level> lg;
logging::add_common_attributes();
auto file_sink = logging::add_file_log(
keywords::file_name = "./logs/L%Y-%m-%d_%3N.log", // one file per date and execution
keywords::rotation_size = 5 * 1024 * 1024, // rotate after 5MB
keywords::target = "./logs",
keywords::min_free_space = 30 * 1024 * 1024,
keywords::auto_flush = true,
keywords::scan_method = boost::log::sinks::file::scan_matching
);
file_sink->set_formatter(&full_detail_formatter);
file_sink->set_filter(
logging::trivial::severity >= logging::trivial::trace
);
auto console_sink = logging::add_console_log(std::clog);
console_sink->set_formatter(&full_detail_formatter);
console_sink->set_filter(
logging::trivial::severity >= logging::trivial::trace
);
logging::core::get()->set_filter(
logging::trivial::severity >= logging::trivial::trace
);
return lg;
}
编辑
似乎有人已经通过在执行 async_read_some
asio::io_service::run
创建线程解决了这个问题 Seems like someone already solved this problem here by creating thread for asio::io_service::run after execution of async_read_some
是的。否则 run()
可能会在任何作品注册之前完成。
它的文档在这里:http://www.boost.org/doc/libs/1_65_0/doc/html/boost_asio/reference/io_service/run/overload1.html
The run() function blocks until all work has finished and there are no more handlers to be dispatched, or until the io_service has been stopped.
可以找到更多解释:
- Confused when boost::asio::io_service run method blocks/unblocks
考虑使用 io_service::work
保留服务:boost asio post not working , io_service::run exits right after post