如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
How to do mutually exclusive read or write operation on a global variable in signal handler and normal function
应用程序是多线程的。在main()
中,我注册SIGUSR1:的信号处理程序
// Global variable to indicate whether directory's
// content needs to be reloaded
bool reload_dir = 0;
int main (int argc, char *argv[])
{
...
signal(SIGUSR1, sigusr1_handler);
...
RunServer(arg1, ...);
return 0;
}
信号处理器:
static void
sigusr1_handler (int signo __unused)
{
reload_dir = 1;
return;
}
以下函数(从main调用(仅由主线程执行:
void
RunServer (arg1, ...)
{
// do some stuffs
...
while (cond != true) {
sleep(1);
}
server_exit();
}
现在,当SIGUSR1被捕获(被包括主线程在内的任何线程捕获(时,我将reload_dir变量设置为1。在RunServer()
中,我将根据该值重新加载目录。但是,我还将全局变量reload_dir
重置为0,以避免无限期地重复加载目录。并且将reload_dir
设置为0将引入竞赛。
既然我们不应该在信号处理程序中使用锁或互斥,那么我如何在不大量更改现有应用程序设计的情况下实现这一点呢。
void
RunServer (arg1, ...)
{
// do some stuffs
...
while (cond != true) {
if (reload_dir) {
// reset reload_dir to avoid loading repeatedly indefinitely
reload_dir = 0; // Race condition?
dir_reinit();
}
sleep(1);
}
server_exit();
}
在派生任何线程之前用pthread_sigmask
阻止SIGUSR1,以便所有线程都继承该掩码。然后,在main()
中,在主循环中使用sigtimedwait
而不是sleep
来检查USR1是否已交付。
int main(...) {
...
sigset_t ss_usr1;
sigemptyset(&ss_usr1);
sigaddset(&ss_usr1, SIGUSR1);
// block SIGUSR1
pthread_sigmask(SIG_BLOCK, &ss_usr1, NULL);
... spawn threads ...
// RunServer
struct timespec patience = { .tv_sec = 1 };
while (! some_condition) {
int s = sigtimedwait(&ss_usr1, NULL, &patience);
if (s == SIGUSR1) dir_reinit();
// handle errors other than timeout appropriately
}
server_exit();
...
}
优点:没有信号处理程序的复杂性(正确地说,你不会因为使用signal
而不是高级sigaction
而受到惩罚;不需要原子标志或sig_atomic_t
;更容易对行为进行推理。
相关文章:
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 当vector是tje全局变量时,c++中vector的内存管理
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 内联函数中具有内部链接的全局变量
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 全局变量 多读取器 一个写入器多线程安全?
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 不同作用域中的静态变量和全局变量
- C++ 在编译时具有函数计算全局变量
- 修改程序的入口点时未调用全局变量的构造函数
- 使用 std::ios_base::Init 正确初始化全局变量
- 为什么我的全局变量似乎没有变化?
- C ++程序如何返回我的数组或写入全局变量
- 为什么我的数组值与此处的全局变量不匹配?
- QT C++中对全局变量的未定义引用
- 跨多个类的全局变量而不会出现重定义错误?
- 赋予全局变量而不是局部变量优先级的函数 - (异常行为)
- C++线程不检测全局变量更改
- 如何在c++中操作全局变量
- 操作全局变量