我正在寻找一种方法(最好使用boost线程),如果没有加入则中断一个线程。我启动多个线程,并希望结束任何未完成200毫秒的线程。我试过这样的事情
boost::thread_group tgroup;
tgroup.create_thread(boost::bind(&print_f));
tgroup.create_thread(boost::bind(&print_g));
boost::this_thread::sleep(boost::posix_time::milliseconds(200));
tgroup.interrupt_all();
现在这个工作,并且所有线程在200毫秒后结束;但是如果它们在200毫秒之前完成,我想尝试加入这些线程,如果没有在一定时间内完成,有没有办法加入和中断?
编辑:在超时之前我需要加入的原因:
我正在创建速度非常重要的服务器。不幸的是,我必须向其他服务器请求一些信息。所以我想并行进行这些调用,并尽快完成。如果服务器耗时太长,我必须忽略来自该服务器的信息,并在没有它的情况下继续。所以我的超时时间是我可以等待的最长时间。当收到所有响应时,能够继续沉思,而不是等待时间超时计时器对我来说是非常有益的。那么我的计划将是什么:
- 获取客户的请求。
- 稀疏信息。
创建帖子
- 向多个其他服务器发送信息。
- 从服务器获取信息。
- 从共享队列上的服务器输出信息。
结束主题
- 来自共享队列的信息。
- 将信息返回给客户
答案 0 :(得分:3)
如果您使用的是最近的Boost和C ++ 11,请使用try_join_for()
(http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html#thread.thread_management.thread.try_join_for)。否则,请使用timed_join()
(http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html#thread.thread_management.thread.timed_join)。
答案 1 :(得分:3)
您想要使用的可能是一组作用域线程,并在超时后调用所有剩余线程上的终止。不幸的是,线程组和范围线程不能一起使用。
线程组类实际上是一个非常简单的容器:如果您没有指向它的指针,则无法删除它的线程,并且您无法获得指向该组创建的线程的指针。类API也没有提供太多。在您的情况下,这对管理层来说有点阻碍。
其余的解决方案依赖于在goup之外创建线程,并让它们在完成之前完成特定的任务。它可以:
管理线程必须在后一组上调用join_all
,并像以前一样对前者采取行动。
using namespace boost;
void thread_end(auto &thmap, thread_group& t1, thread_group& t2, auto &task){
task();
thread *self = thmap[this_thread::get_id()];
t1.remove_thread(&self);
t2.add_thread(&self);
}
std::map<thread::id, thread *> thmap;
thread_group trunninggroup;
thread_group tfinishedgroup;
thread *th;
th = new thread(
bind(&thread_end, thmap, trunninggroup, tfinishedgroup, bind(&print_f)));
thmap[th->get_id()] = th;
trunninggroup.add_thread(th);
th = new thread(
bind(&thread_end, thmap, trunning_group, tfinishedgroup, bind(&print_g)));
thmap[th->get_id()] = th;
trunninggroup.add_thread(th);
boost::this_thread::sleep(boost::posix_time::milliseconds(200));
tfinishedgroup.join_all();
trunninggroup.interrupt_all();
但是,如果您确实希望管理线程在实际发生时被通知线程结束,那么这并不理想(而且我不确定它是否会做任何有用的事情)。获得通知的解决方案可能是:
timed_wait
但你必须做一些时间计算以跟踪通知后的剩余时间,并在剩下的时间内恢复睡眠。这完全取决于用于该任务的Duration类。
从整体上看,我会尝试一种完全不同的方法:我不认为终止已经完成的线程是一个问题,所以我会将它们全部留在组中,并使用该组来创建它们,正如你的代码所展示的那样。
但是,我会尝试在所有线程完成后或超时后唤醒管理线程。这不仅仅是thread_group
类提供的功能,但可以使用自定义信号量或boost::barrier
的修补版本来完成,以便进行定时等待。
基本上,您为组中的线程数加一(主线程)设置了障碍,并让主线程时间等待它。每个工作线程都会完成其工作,完成后,将其结果发布到队列中,并在屏障上发布wait
。如果所有工作线程完成任务,则每个人都会等待并触发屏障。
然后主线程(以及所有其他线程,但无关紧要)唤醒并可以通过终止组并处理结果来继续。否则,它会在超时时唤醒,并且无论如何都会这样做。
boost::barrier
的修补不应该太困难,您只需要复制wait
方法并将条件变量wait
替换为timed_wait
(I没有看代码,这个假设可能完全是标记虽然)。否则,我提供了this question的示例信号量实现,这也不难修补。
最后一个考虑因素:终止线程通常不是最好的方法。你应该尝试发信号通知他们必须中止的线程,然后等待它们,或者以某种方式将其未完成的任务传递给一个辅助线程,该线程应该连续清理。然后你的线程组将准备好处理下一个任务,你不必一直销毁和创建线程,这是一个非常昂贵的操作。它需要在应用程序的上下文中形成任务的概念,并使线程在循环上运行以获取新任务并处理它们。