有没有办法从另一个线程中取消boost::thread,如下所示?:
boost::thread* thread1(0);
boost::thread* thread2(0);
thread2 = new boost::thread([&](){
//some expensive computation that can't be modified
if(thread1)
thread1->interrupt();
});
thread1 = new boost::thread([&]() {
//some other expensive computation that can't be modified
if(thread2)
thread2->interrupt();
});
thread1->join();
thread2->join();
delete thread1;
delete thread2;现在,这两个昂贵的计算都会在不被中断的情况下完成。我认为连接将被视为中断点,并且主线程将在两个代价高昂的计算中的一个完成后继续。
发布于 2015-06-02 04:56:21
发布于 2016-02-12 06:58:09
对于兼容POSIX的系统(例如,Linux),不可移植的解决方案是先使用pthread_cancel(),然后在Boost线程的native_handle()成员上使用pthread_join(),该成员的类型为pthread_t (同样,仅在兼容POSIX的系统上使用)。我不能为其他系统说话,比如Windows)。
此外,您必须使用boost::scoped_thread而不仅仅是boost::thread,这样您就可以“覆盖”(不是OO意义上的) Boost将在线程被销毁时执行的联接/分离行为。这是必要的,因为当您在boost::thread上调用pthread_cancel和pthread_join时,boost::thread对象仍然是“可接合的”(即boost::thread::joinable()返回true),因此析构函数将根据documentation表现出未定义的行为。
话虽如此,如果在您的应用程序中需要像这样的与平台相关的取消线程的解决方案,我不确定使用boost::threads而不是普通的pthreads能获得多少好处;不过,我认为可能有这样的用例。
下面是一个代码示例:
// compilation: g++ -pthread -I/path/to/boost/include -L/path/to/boost/libs -lboost_thread main.cpp
#include <cstdio>
#include <pthread.h>
#include <boost/thread/scoped_thread.hpp>
typedef struct pthreadCancelAndJoin
{
void operator()(boost::thread& t)
{
pthread_t pthreadId = t.native_handle();
int status = pthread_cancel(pthreadId);
printf("Cancelled thread %lu: got return value %d\n", pthreadId, status);
void* threadExitStatus;
status = pthread_join(pthreadId, &threadExitStatus);
printf("Joined thread %lu: got return value %d, thread exit status %ld\n",
pthreadId, status, (long)threadExitStatus);
}
} pthreadCancelAndJoin;
void foo()
{
printf("entering foo\n");
for(int i = 0; i < 2147483647; i++) printf("f"); // here's your 'expensive computation'
for(int i = 0; i < 2147483647; i++) printf("a");
printf("foo: done working\n"); // this won't execute
}
int main(int argc, char **argv)
{
boost::scoped_thread<pthreadCancelAndJoin> t1(foo);
pthread_t t1_pthread = t1.native_handle();
sleep(1); // give the thread time to get into its 'expensive computation';
// otherwise it'll likely be cancelled right away
// now, once main returns and t1's destructor is called, the pthreadCancelAndJoin
// functor object will be called, and so the underlying p_thread will be cancelled
// and joined
return 0;
}当线程到达“取消点”时,pthread_cancel()将取消线程(假设cancel type and cancel state是它们的默认值,boost::thread对象就是这种情况);有关所有取消点的列表,请参阅pthreads man page。您会注意到,这些取消点包括许多更常见的系统调用,如write、read、sleep、send、recv、wait等。
如果您的“昂贵的计算”包括在最低级别(例如,在代码示例中,printf最终调用write)调用这些调用的任何,那么它将被取消。
最棒的是,Valgrind报告此解决方案没有内存泄漏或内存错误。
最后,请注意您在问题中的误解:
我认为joins将被视为中断点...
就这一点而言,join或任何boost::thread中断函数仅被视为调用 it的线程的中断点。由于您的主线程正在调用join(),因此主线程是遇到中断点的线程,而不是它试图加入的线程。例如,如果你在某个线程中调用thread1.interrupt(),然后thread1调用thread2.join(),那么thread1就是那个被中断的线程。
https://stackoverflow.com/questions/30582946
复制相似问题