Boost::thread::interrupt() 对于不同的中断点,其行为不同.为什么
Boost::thread::interrupt() behaves differently for different interruption points. Why?
我目前正在编写一个使用提升线程的DLL。我在使用 boost::thread::interrupt(( 并捕获thread_interrupted异常时遇到了问题。对于一些中断 ponts,中断被抛出并在线程中捕获,而对于其他中断,中断在调用 thread.interrupt(( 的地方被抛出。为什么会这样?我写了一个基本的例子来说明我的观点,它位于这篇文章的底部
程序启动一个线程,该线程使用其中一个工作器函数,每个工作器函数中都有不同的中断点。当用户按回车键时,线程被中断,程序将关闭。在打印每个语句之前,都会打印线程 ID,以便我们可以看到正在发生的事情。
我期待这样的东西:
13c4 main thread
790 worker thread
790 thread iteration 1 Press Enter to stop
790 thread iteration 2 Press Enter to stop
790 thread iteration 3 Press Enter to stop
790 Thread is stopped in ThreadFunction
13c4 main: thread ended
Process returned 0 (0x0) execution time : 0.200 s
Press any key to continue.
主线程与工作线程并行运行的位置。当用户按 Enter 时,中断在主线程中调用,但在工作线程中捕获。然后销毁线程。然后主线程继续,程序退出。
我在我尝试过的所有中断点(除了 interruption_point(((中看到的是中断被捕获在主线程中,似乎它是继续执行主线程的工作线程。这样:
1364 main thread
964 worker thread
964 thread iteration 1 Press Enter to stop
964 thread iteration 2 Press Enter to stop
964 thread iteration 3 Press Enter to stop
964 Thread is joined
964 main: thread ended
Process returned 0 (0x0) execution time : 1.510 s
Press any key to continue.
是什么原因造成的?例如,在使用条件变量时,如何捕获工作器函数中的中断?我在某处犯了错误吗?
我的代码:
#define BOOST_THREAD_USE_LIB 1
#define BOOST_SYSTEM_NO_DEPRECATED 1
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501
#include <boost/thread.hpp>
#include <iostream>
using namespace std;
void ThreadFunctionSleep()
{
cout << boost::this_thread::get_id() << " worker thread " << endl;
int counter = 0;
while(1)
{
cout << boost::this_thread::get_id() << " thread iteration " << ++counter << " Press Enter to stop" << endl;
try
{
boost::this_thread::sleep(boost::posix_time::milliseconds(5000));
}
catch(boost::thread_interrupted&)
{
cout << boost::this_thread::get_id() << " Thread is stopped in ThreadFunction " << endl;
return;
}
}
}
void ThreadFunctionSleep2()
{
cout << boost::this_thread::get_id() << " worker thread " << endl;
int counter = 0;
try
{
cout << boost::this_thread::get_id() << " thread iteration " << ++counter << " Press Enter to stop" << endl;
while(1)
{
boost::this_thread::sleep(boost::posix_time::milliseconds(5000));
}
}
catch(boost::thread_interrupted&)
{
cout << boost::this_thread::get_id() << " Thread is stopped in ThreadFunction " << endl;
return;
}
}
void ThreadFunctionInterruptionPoint()
{
cout << boost::this_thread::get_id() << " worker thread " << endl;
int counter = 0;
while(1)
{
cout << boost::this_thread::get_id() << " thread iteration " << ++counter << " Press Enter to stop" << endl;
try
{
boost::this_thread::interruption_point();
}
catch(boost::thread_interrupted&)
{
cout << boost::this_thread::get_id() << " Thread is stopped in ThreadFunction " << endl;
return;
}
}
}
bool myPredicate()
{
return false;
}
boost::condition_variable full;
boost::condition_variable empty;
boost::mutex fullMut;
boost::mutex emptyMut;
void waitedConditionVariable()
{
try
{
while(1)
{
boost::system_time const timeout=boost::get_system_time()+ boost::posix_time::milliseconds(1000);
boost::unique_lock<boost::mutex> lock(fullMut);
std::cout << boost::this_thread::get_id()<< " waiting for condition variable or for timeout" << std::endl;
if (full.timed_wait(lock, timeout, myPredicate))
{
std::cout << boost::this_thread::get_id()<< " condition variable signalled " << std::endl;
}
else
{
std::cout << boost::this_thread::get_id()<< " condition variable timeout. " << std::endl;
}
}
}
catch(boost::thread_interrupted & )
{
std::cout<< boost::this_thread::get_id() << " waitedConditionVariable thread_interrupted " << std::endl;
return;
}
catch (std::exception& e)
{
std::cerr << boost::this_thread::get_id()<< " waitedConditionVariable Thread "
<< " caught std::exception" << e.what() << std::endl;
return;
}
catch(...)
{
std::cout<< boost::this_thread::get_id() << " waitedConditionVariable other" << std::endl;
return;
}
}
void waitedConditionVariable2()
{
while(1)
{
try
{
boost::system_time const timeout=boost::get_system_time()+ boost::posix_time::milliseconds(1000);
boost::unique_lock<boost::mutex> lock(fullMut);
std::cout << boost::this_thread::get_id()<< " waiting for condition variable or for timeout" << std::endl;
if (full.timed_wait(lock, timeout, myPredicate))
{
std::cout << boost::this_thread::get_id()<< " condition variable signalled " << std::endl;
}
else
{
std::cout << boost::this_thread::get_id()<< " condition variable timeout. " << std::endl;
}
}
catch(boost::thread_interrupted & )
{
std::cout<< boost::this_thread::get_id() << " waitedConditionVariable thread_interrupted " << std::endl;
return;
}
catch (std::exception& e)
{
std::cerr << boost::this_thread::get_id()<< " waitedConditionVariable Thread "
<< " caught std::exception" << e.what() << std::endl;
return;
}
catch(...)
{
std::cout<< boost::this_thread::get_id() << " waitedConditionVariable other" << std::endl;
return;
}
}
}
void normalConditionVariable()
{
try
{
boost::unique_lock<boost::mutex> lock(fullMut);
while(1)
{
std::cout << boost::this_thread::get_id()<< " waiting for condition variable " << std::endl;
full.wait(lock);
std::cout << boost::this_thread::get_id()<< " wait done " << std::endl;
}
}
catch(boost::thread_interrupted & )
{
std::cout<< boost::this_thread::get_id() << " normalConditionVariable thread_interrupted " << std::endl;
return;
}
catch (std::exception& e)
{
std::cerr << boost::this_thread::get_id()<< " normalConditionVariable Thread "
<< " caught std::exception" << e.what() << std::endl;
return;
}
catch(...)
{
std::cout<< boost::this_thread::get_id() << " normalConditionVariable other" << std::endl;
return;
}
}
void normalConditionVariable2()
{
while(1)
{
boost::unique_lock<boost::mutex> lock(fullMut);
try
{
std::cout << boost::this_thread::get_id()<< " waiting for condition variable " << std::endl;
full.wait(lock);
std::cout << boost::this_thread::get_id()<< " wait done " << std::endl;
}
catch(boost::thread_interrupted & )
{
std::cout<< boost::this_thread::get_id() << " normalConditionVariable thread_interrupted " << std::endl;
return;
}
catch (std::exception& e)
{
std::cerr << boost::this_thread::get_id()<< " normalConditionVariable Thread "
<< " caught std::exception" << e.what() << std::endl;
return;
}
catch(...)
{
std::cout<< boost::this_thread::get_id() << " normalConditionVariable other" << std::endl;
return;
}
}
}
int main()
{
cout << boost::this_thread::get_id() << " main thread " << endl;
// Start thread
//use thes functions:
// ThreadFunctionSleep
// ThreadFunctionSleep2
//ThreadFunctionInterruptionPoint
//ThreadFunctionInterruptionPoint2
// waitedConditionVariable
// waitedConditionVariable2
// normalConditionVariable
// normalConditionVariable2
boost::thread t(&waitedConditionVariable2);
// Wait for Enter
char ch;
cin.get(ch);
// Ask thread to stop
try
{
t.interrupt();
}
catch(boost::thread_interrupted&)
{
cout << boost::this_thread::get_id() << " Thread is stopped" << endl;
}
// Join - wait when thread actually exits
try
{
t.join();
}
catch(boost::thread_interrupted&)
{
cout << boost::this_thread::get_id() << " Thread is joined" << endl;
}
catch(...){
cout << boost::this_thread::get_id() << " other exception" << endl;
}
cout << boost::this_thread::get_id() << " main: thread ended" << endl;
return 0;
}
我正在使用提升 1.53.0 和 MinGW 4.4.1。我正在使用运行时链接静态多线程库进行提升::线程和提升::系统
感谢您的帮助
应该
重新抛出异常,否则boost::thread
不会真正中断。
请尝试下面的代码。您可以尝试不同的join()
位置以查看显示线程状态的不同输出。
#include <iostream>
#include <boost/thread.hpp>
void foo()
{
while(true) try
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
std::cout << "Thread is running..." << std::endl;
}
catch (boost::thread_interrupted&)
{
std::cout << "The thread is interrupted" << std::endl;
throw boost::thread_interrupted();
}
}
int main(int argc, char *argv[])
{
boost::thread t(foo);
std::cout << "Press Enter to quit..." << std::endl;
std::cin.get();
t.interrupt();
//t.join();
if (!t.try_join_for(boost::chrono::milliseconds(1)))
{
std::cout << "Thread is running." << std::endl;
}
else
{
std::cout << "Thread is not running." << std::endl;
}
//t.join();
boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
// The out put should be "Thread is running.", because thread is not joinalb, the test function itself is wrong.
if (!t.try_join_for(boost::chrono::milliseconds(1)))
{
std::cout << "Thread is running." << std::endl;
}
else
{
std::cout << "Thread is not running." << std::endl;
}
}
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 为什么会发生堆损坏
- 为什么使用 "this" 指针调用派生成员函数?
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么比较运算符如此快速
- 为什么 Serial.println(<char[]>);返回随机字符?
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 为什么断点显示数组的第二个值是一个大数字?额外学分工作
- 为什么在c++中使用Delete[]会出现跟踪/断点错误
- 为什么我的 MPI 应用程序会触发断点?
- 为什么GDB会自动继续在断点上继续
- 为什么断点在 .h 文件中跳来跳去
- 为什么代码在代码块中的断点处没有中断
- 为什么数据断点不能在未对齐的地址上工作
- 为什么GDB没有在断点上停止
- Visual Studio - 为什么断点在我的C++代码中跳转