gpt4 book ai didi

c++ - 在信号处理程序中使用互斥体

转载 作者:行者123 更新时间:2023-12-03 08:47:33 25 4
gpt4 key购买 nike

我有一个多线程应用程序,需要在出现中断、终止等信号时优雅地停止它。

这里有一个片段来说明逻辑的相关部分。

std::atomic_bool running = true;
std::mutex mutex;
std::condition_variable condition;

void signal_handler(int signal)
{
// in another thread `[&]() { return !running || something_to_do_conditon; } == false`
// what means continue to wait
running = false;
condition.notify_one();
// another thread goes to sleep
}

void run() {
while(true) {
std::unique_lock lock(mutex);
condition.wait_for(lock, std::chrono::hours(1), [&]() { return !running || something_to_do_conditon; });

if (!running) {
return;
}

// do smth
}
}

int main()
{
// Install a signal handler
std::signal(SIGINT, signal_handler);
std::signal(SIGTERM, signal_handler);

std::thread thread(run);
thread.join();
}

正如您在 signal_handler 中看到的,甚至可能出现 running 设置为 falsecondition 的情况> 被通知仍然存在线程休眠 1 小时的场景(用内嵌注释进行描述)。发生这种情况是因为 running 变量周围没有互斥体。这允许线程锁定互斥体并在设置变量之前检查条件。如果我添加类似的内容

  {
std::lock_guard<std::mutex> lock(mutex);
running = false;
}

在处理程序中可以避免。

那么问题是如何使用(是否可能)互斥体而不会出现潜在的死锁或任何其他问题。任何其他削弱 sleep 线程信号的技巧。

最佳答案

在 pthreads 程序中处理信号的可靠方法是屏蔽您希望在每个线程中处理的所有信号,并创建一个专用的信号处理线程,该线程循环调用 sigwaitinfo() (或sigtimedwait())。

然后,信号处理线程可以使用普通的互斥锁保护共享变量和 pthread_cond_signal()/pthread_cond_broadcast() 唤醒来通知其他线程有关收到的信号。

在您的示例中,如果以这种方式编写,专用信号处理线程可以在更改 running 标志之前安全地锁定互斥体,因为它只是在普通线程上下文中而不是信号处理程序。

关于c++ - 在信号处理程序中使用互斥体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60803245/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com