我正在做一种shell:根据用户的条目,我必须调用一些函数。我无法修改那些被调用函数的内容,因为我的程序只是一个客户端而且没有它们的可见性。
但是我希望用户可以使用CTRL+C
来终止呼叫。这是最小的代码:
#include <csignal>
#include <iostream>
#include <unistd.h>
void do_thing(void)
{
std::cout << "entering in do_thing()\n";
while(42)
::sleep(1);
}
extern "C" {
void signal_handler(int);
}
class Shell
{
friend void signal_handler(int);
public:
static Shell & Instance(void)
{
static Shell instance;
return instance;
}
int run(void)
{
std::string buff;
while ((std::cin >> buff))
{
if (buff == "foo")
do_thing(); // this must be terminable
else
std::cout << "(nothing)\n";
}
return 0;
}
private:
Shell(void)
{
::signal(SIGINT, signal_handler);
}
void signal(int sig)
{
if (sig == SIGINT)
;// must terminal the function call
}
};
extern "C" {
void signal_handler(int sig)
{
Shell::Instance().signal(sig);
}
}
int main(void)
{
return Shell::Instance().run();
}
我考虑了三种可能性:
std::thread
的线程类,并使用kill()
方法抛出异常。函数调用在try-catch块中。它可以工作,但这是一个糟糕的解决方案,因为无法调用析构函数,并且永远不会释放资源。fork
,但我认为只是有可能中断函数调用。你怎么能做到这一点?什么是更好的解决方案?
注意:我删除了旧帖子,因为它是近距离请求的,并考虑了C / C ++标签。
答案 0 :(得分:2)
基本上,不,没有标准为什么要在C ++中中断线程。线程合作运行,因此,他们需要“放弃”控制。
如果do_thing
的代码是可修改的,那么您可以创建一个标志(原子)来表示线程应该放弃并退出。这可以由线程定期检查并根据需要完成。
鉴于do_thing
的代码不可修改,有一个小机会窗口可用于“杀死”或“取消”该线程(尽管它不会是“标准”,支持将仅限于目标平台。
std::thread
提供了一个函数来检索实现定义的native_handle()
。一旦获得(并转换),它就可以用来杀死或取消线程。
如果正在使用pthread,请参阅pthread_kill
(或pthread_cancel
,如果目标线程支持)。
在Windows上,请参阅TerminateThread
功能。
警告;除了所需的平台特定代码之外,线程终止通常会使该线程上的对象处于“空白”状态,并与它们一起保留它们控制的资源。