我正在尝试一些简单的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.
发生了什么事?
答案 0 :(得分:1)
你不应该调用start_thread吗?
这不是必需的,因为它是泄露的内部实施细节:
在我的代码中,我不小心调用了这个方法,导致我的回调被启动了两次。
因此,您获得std::cout
,y
的非同步访问权限,从而导致 Undefined Behaviour
此修订可在此提交中找到:https://github.com/boostorg/thread/commit/750c849b0f0dff79a289111955260a4147ac7f59
答案 1 :(得分:0)
即使<{1}}中的 公共方法start_thread
,它也不在documentation中。那是reason:
启动线程
通过将可调用的可调用类型的对象传递给构造函数来启动新线程。 [...]
如果您希望使用需要提供参数的函数或可调用对象构造boost :: thread实例,可以通过将其他参数传递给boost :: thread构造函数来完成:
无论您使用哪种构造函数,该线程都已在运行:
class 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;
}
实现。