如果没有连接,则中断线程

时间:2013-04-10 14:51:41

标签: c++ multithreading boost boost-thread

我正在寻找一种方法(最好使用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毫秒之前完成,我想尝试加入这些线程,如果没有在一定时间内完成,有没有办法加入和中断?

编辑:在超时之前我需要加入的原因:

我正在创建速度非常重要的服务器。不幸的是,我必须向其他服务器请求一些信息。所以我想并行进行这些调用,并尽快完成。如果服务器耗时太长,我必须忽略来自该服务器的信息,并在没有它的情况下继续。所以我的超时时间是我可以等待的最长时间。当收到所有响应时,能够继续沉思,而不是等待时间超时计时器对我来说是非常有益的。那么我的计划将是什么:

- 获取客户的请求。

- 稀疏信息。

创建帖子

- 向多个其他服务器发送信息。

- 从服务器获取信息。

- 从共享队列上的服务器输出信息。

结束主题

- 来自共享队列的信息。

- 将信息返回给客户

2 个答案:

答案 0 :(得分:3)

答案 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的示例信号量实现,这也不难修补。

最后一个考虑因素:终止线程通常不是最好的方法。你应该尝试发信号通知他们必须中止的线程,然后等待它们,或者以某种方式将其未完成的任务传递给一个辅助线程,该线程应该连续清理。然后你的线程组将准备好处理下一个任务,你不必一直销毁和创建线程,这是一个非常昂贵的操作。它需要在应用程序的上下文中形成任务的概念,并使线程在循环上运行以获取新任务并处理它们。