【问题标题】:C++ Continue the execution after signal handlerC++ 在信号处理程序之后继续执行
【发布时间】:2020-09-20 20:48:00
【问题描述】:

我正在尝试在 C++ 中管理信号,然后继续正常执行程序。我使用信号而不是异常,因为在未连接传感器时程序会自行阻塞(我无法更改)。

引发信号的代码部分使用线程作为计时器。由于线程不能抛出异常,所以我决定发出一个信号(在这种情况下为 SIGTERM)。

当我尝试以与异常但使用信号处理程序相同的方式继续程序时,问题就开始了。我利用 setjmp 库来解决这个问题:

jmp_buf gBuffer;
void signalHandler(int signal) {
    longjmp(gBuffer, 1);
}

int main() {
    std::signal(SIGTERM, signalHandler);

    if (setjmp(gBuffer) == 0) {
        /* ---------------------
           Part of code that raise the signal
        --------------------- */
    }
}

运行正常,但是程序结束时出现内存错误:

*** stack smashing detected ***: <unknown> terminated
Aborted (core dumped)

在调试模式下执行程序时的回溯是:

Thread 2 "EXECUTABLE_FILE" received signal SIGTERM, Terminated.
[Switching to Thread 0x7ffff01f2700 (LWP 31718)]
raise (sig=<optimized out>) at ../sysdeps/unix/sysv/linux/raise.c:51
51  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  raise (sig=<optimized out>) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff78531ab in "THREAD THAT RAISE THE SIGNAL" (futureObj=...)
    at "LINE THAT RAISE THE SIGNAL"
#2  0x00007ffff7856ffd in std::__invoke_impl<void, void (*)(std::future<void>), std::future<void> >
    (__f=<optimized out>) at /usr/include/c++/7/bits/invoke.h:60
#3  std::__invoke<void (*)(std::future<void>), std::future<void> > (__fn=<optimized out>)
    at /usr/include/c++/7/bits/invoke.h:95
#4  std::thread::_Invoker<std::tuple<void (*)(std::future<void>), std::future<void> > >::_M_invoke<0ul, 1ul> (this=<optimized out>) at /usr/include/c++/7/thread:234
#5  std::thread::_Invoker<std::tuple<void (*)(std::future<void>), std::future<void> > >::operator()
    (this=<optimized out>) at /usr/include/c++/7/thread:243
#6  std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::future<void>), std::future<void> > > >::_M_run (this=<optimized out>) at /usr/include/c++/7/thread:186
#7  0x00007ffff6e41d80 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8  0x00007ffff714c6db in start_thread (arg=0x7ffff01f2700) at pthread_create.c:463
#9  0x00007ffff688988f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

如果有人可以帮助我,我真的很感激。我还可以更改引发信号的代码部分,引发异常,但我不知道如何在线程中执行此操作。

【问题讨论】:

  • 我真的建议你不要使用longjmp。使用std::condition_variable 而不是来自线程的信号和跳远。
  • 信号处理程序通常在它们自己的上下文中被调用。通过长跳出信号处理程序,您可以有效地继续在信号处理程序的上下文中运行。没有返回内核空间(对于 POSIX 系统),因此它认为信号处理程序从未返回。
  • 我不明白为什么你不能使用 excaptions 并且可以使用信号?在这种情况下,关于传感器的解释至少很奇怪。也许你的编译器不支持异常?

标签: c++ linux multithreading signals signal-handling


【解决方案1】:

您无法按照您直接设想的方式进行操作 - 抱歉。是的,您的信号处理程序被调用,但由于limitations 列出的信号处理程序(例如. 新信号可能会被阻止发出等)。

因此,您的信号处理程序应该设置某种标志,例如。原子布尔或条件变量或您喜欢的任何方法。然后从信号处理程序返回。然后在“违规代码”附近有一个循环,可以检查它,然后能够返回/展开/终止计时器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多