如何"interrupt"函数调用?

How to "interrupt" a function call?

本文关键字:函数调用 interrupt 如何      更新时间:2023-10-16

我正在做一种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,但我认为仅仅获得中断函数调用的可能性是过分的
  • 我试图从信号处理程序中抛出一个异常,但我发现这是个坏主意,因为这是非常依赖编译器/OS的代码

你怎么能做那件事?什么是更好的解决方案?

注意:我删除了旧的帖子,因为它是关闭请求的,并考虑了C/C++标记。

从本质上讲,不,在C++中没有中断线程的标准原因。线程协同运行,因此,它们需要"放弃"控制。

如果do_thing的代码是可修改的,那么您可以创建一个标志(原子)来表示线程应该放弃并退出。这可以由线程定期检查,并根据需要完成。

鉴于do_thing的代码是不可修改的,有一个小的机会窗口可以用来"杀死"或"取消"线程(尽管它不是"标准"的,并且支持将仅限于目标平台)。

std::thread提供了一个检索实现定义的native_handle()的函数。一旦获得(并转换),它就可以用来终止或取消线程。

  • 如果使用pthreads,请参阅pthread_kill(或者pthread_cancel,如果目标线程支持)。

  • 在窗口中,请参阅TerminateThread函数。

请注意;除了所需的特定于平台的代码外,线程终止通常会将该线程上的对象以及它们所控制的资源留在"边缘地带"。