Boost::thread 在简单循环期间崩溃
Posted
技术标签:
【中文标题】Boost::thread 在简单循环期间崩溃【英文标题】:Boost::thread crashes during simple loop 【发布时间】:2014-12-05 11:48:41 【问题描述】:我正在尝试一些简单的boost::thread
代码,如下:
#include <iostream>
#include <boost/thread.hpp>
void InputLoop()
std::cout << "Loop start" << std::endl;
int y = 0;
while (1)
std::cout << "y = " << y << std::endl;
y++;
std::cout << "Loop end" << std::endl;
int main()
std::cout << "Main start" << std::endl;
boost::thread t(InputLoop);
t.start_thread();
while (1)
int x = 0;
std::cout << "Main end" << std::endl;
return 0;
这给出了输出:
Main start
Loop start
y = 0
y = 1
y = 2
.
.
.
The program has unexpectedly finished
所以,它在InputLoop()
期间崩溃了。发生崩溃时y
的值在不同的运行中有所不同,范围从大约0到大约10000。
发生了什么事?
【问题讨论】:
它在coliru.stacked-crooked.com 上运行。虽然,没有 t.start_thread();并带有“警告:未使用的变量'x' [-Wunused-variable] int x = 0;” 我需要升级或降级我的 boost-pick。因为start_thread
在我的平台上声明private
访问权限(OSX 10.7.1)
@WhozCraig - 抱歉,已编辑,忘记提及 - "/usr/local/include/boost/thread/detail/thread.hpp:177:14: error: 'void boost::thread: :start_thread()' 是私有的 void start_thread()"。只是想指出它不会“意外崩溃”。
【参考方案1】:
你不应该调用 start_thread 吗?
这不是必需的,因为它是泄露的内部实现细节:
https://svn.boost.org/trac/boost/ticket/9632在我的代码中,我不小心调用了这个方法,导致我的回调被启动了两次。
所以你获得了对std::cout
、y
的非同步访问,这导致Undefined Behaviour
在此提交中找到修复:https://github.com/boostorg/thread/commit/750c849b0f0dff79a289111955260a4147ac7f59
【讨论】:
【参考方案2】:即使在class thread
中有一个公共方法start_thread
,它也不在documentation 中。那是reason:
启动线程
通过将可调用类型的对象传递给构造函数来启动新线程,该对象可以在没有参数的情况下调用。 [...]
如果您希望使用需要提供参数的函数或可调用对象来构造 boost::thread 的实例,可以通过向 boost::thread 构造函数传递额外的参数来完成:
不管你使用哪个构造函数,线程已经在运行:
// <boost/thread/detail/thread.hpp>
template <
class F
>
explicit thread(BOOST_THREAD_RV_REF(F) f
//, typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
):
thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f))))
start_thread();
start_thread
是如何定义的?
void start_thread()
if (!start_thread_noexcept())
boost::throw_exception(thread_resource_error());
start_thread_noexcept
实际上不在标题中,而是libboost_thread
的一部分:
// boost/lib/thread/src/thread.cpp
bool thread::start_thread_noexcept()
thread_info->self=thread_info;
int const res = pthread_create(&thread_info->thread_handle, 0, &thread_proxy, thread_info.get());
if (res != 0)
thread_info->self.reset();
return false;
return true;
您实际上创建了两个线程。它(可能)是 thread_proxy
实现创建了您的行为。
【讨论】:
以上是关于Boost::thread 在简单循环期间崩溃的主要内容,如果未能解决你的问题,请参考以下文章
C++ boost::asio::io_service创建线程池thread_group简单实例
C++ boost::asio::io_service创建线程池thread_group简单实例
Boost.Thread 链接 - boost_thread 与 boost_thread-mt