2015-11-10 36 views
0

我想知道是否有一种很好的方法可以在一段时间后终止用C++ 11编写的进程?如何干净地终止C++ 11中的进程?

以我过程我有与运行可能在通信处理被阻止主程序纯虚函数run()一个主类。我想我的run()函数被迫在一段时间后(即使被阻塞)和我的主类(以及成员的所有析构函数)的析构函数被完成。

现在我有一个通过回调调用std::terminate一个计时器。

namespace Timer 
{ 
    void start(Duration time, function<void()> task) 
    { 
     thread([time, task]() { 
      this_thread::sleep_for(time); 
      task(); 
     }).detach(); 
    } 
} 
+1

如果'run()'函数不会返回,那么不能完全结束程序。也许你可以在一个线程中运行'run()',并调用'thread :: detach()':main析构函数会被调用,但我不会称它为_clean_。 – rodrigo

+1

我也遇到过这个问题,因为程序可能会被卡在通信中。我已经添加了心跳meachanism,所以我知道每X秒(在我的情况下,每45秒)一条消息将被接收和发送,然后在一分钟超时。所以我从来没有遇到过困扰并等待消息的情况。当然,最糟糕的情况是该程序需要45秒才能关闭,但干净了! – Nidhoegger

+0

如果一个(未分离的)线程被阻塞,它不能在没有先解锁的情况下被正常终止。您必须通过_e.g._语法来控制这种语法,使用wait/notify或使用'wait_for'或类似方法定期检查状态。 – Snps

回答

1

最好的解决办法是在一个线程包run()

std::thread([&]() 
{ 
    run(); 
    finish.notify_all(); 
}).detach(); 

std::unique_lock<std::mutex> lock(waitFinish); 
finish.wait_for(lock, time); 
1

我猜你是在Linux或其他POSIX系统上。 Event loops和轮询在C++ 11中不是标准化的,并且需要操作系统特定的东西。

你的事件循环应该永远不会被阻塞很长一段时间。它应该有一些有限的 - 不要太大 - 超时。在POSIX上,在您的事件循环中使用poll(2),并有合理的超时时间(例如一秒)。或者,使用pipe(内部流程)来触发事件循环(使其他线程 - 或者甚至是一个信号handler-会write(2)上管,事件循环将轮询它和read它,可能会停止,因此,从run返回)

另请参阅thisthat的相关提示。

2

真正的解决办法是处理的原因,而不是症状:

  • 症状:run功能永远不会结束
  • 原因:通信请求永远不会结束

最通信(输入)功能是可中断的,或者有本地超时。如果你的通信例程没有本地超时,你可以(也许)以一种方式使用alarm Posix调用来包装它们,它应该干净地中断它们并允许运行函数干净地退出。

你只需要注意一点alarm使用信号引擎盖下的事实,所以你一定不能阻止SIG_ALRM,但你可以用它来安装存储地方它已被称为信号处理程序。

恕我直言,这将是更简单,更清洁,并用比std::terminate直接终止程序较好的分离关注。

以上只涉及其中run永远不会结束的情况下。如果您想限制运行时间,则应在代码中确定可中断位置,如果允许运行时间耗尽,则测试您的代码,并始终在所有可能阻塞的通信IO上放置超时。

+0

你不回答我的问题。 'run()'结束。但可能需要比预期更多的时间。如果太长,我想强制run()完成。它可能被阻塞在通信阅读或不通过。 – didil