如何"interrupt"一个函数调用?

How to "interrupt" a function call?

我正在做一种 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();
}

我考虑了三种可能性:

你怎么做到的?什么是更好的解决方案?

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

基本上,不,在 C++ 中没有中断线程的标准。线程 运行 合作,因此,它们需要 "give up" 控制。

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

鉴于 do_thing 的代码不可修改,有一个小的 window 机会可以用来 "kill" 或"cancel" 线程(虽然它不会 "standard" 并且支持将仅限于目标平台)。

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

注意;除了所需的平台特定代码外,线程终止通常会将该线程上的对象留在 "limbo" 中,并与它们一起保留它们控制的资源。