Multithreading 使用sigprocmask实现锁

Multithreading 使用sigprocmask实现锁,multithreading,linux-kernel,signals,Multithreading,Linux Kernel,Signals,我在Linux内核2.4中实现用户线程,并使用ualarm调用线程之间的上下文切换 我们有一个要求,线程库的函数应该不受线程上下文切换机制的干扰,所以我研究了阻塞信号,了解到使用sigprocmask是实现这一点的标准方法 但是,要实现这一点,我似乎需要做很多工作: sigset_t new_set, old_set; sigemptyset(&new_set); sigaddset(&new_set, SIGALRM); sigprocmask(SIG_BLOCK, &

我在Linux内核2.4中实现用户线程,并使用ualarm调用线程之间的上下文切换

我们有一个要求,线程库的函数应该不受线程上下文切换机制的干扰,所以我研究了阻塞信号,了解到使用sigprocmask是实现这一点的标准方法

但是,要实现这一点,我似乎需要做很多工作:

sigset_t new_set, old_set;

sigemptyset(&new_set);
sigaddset(&new_set, SIGALRM);
sigprocmask(SIG_BLOCK, &new_set, &old_set);
这会阻止SIGALARM,但它会通过3次函数调用实现这一点!在运行这些函数所需的时间内,可能会发生很多事情,包括发送的信号。 我缓解这种情况的最好办法是暂时禁用ualarm,如下所示:

sigset_t new_set, old_set;

time=ualarm(0,0);
sigemptyset(&new_set);
sigaddset(&new_set, SIGALRM);
sigprocmask(SIG_BLOCK, &new_set, &old_set);
ualarm(time, 0);

这很好,只是感觉很冗长。难道没有更好的办法吗

您会发现中的
sigeptyset()
sigaddset()
只是宏或内联函数,因此它们在代码中内联执行。调用它们时只需使用堆栈变量


但是,为什么不在代码的单线程启动部分中执行此操作?我还怀疑对sigprocmask的函数调用将是原子的。阻止信号并不意味着您的代码将是不可中断的

顺便说一句,我不确定您是如何使用ualarm的,但是如果您在第一次调用它时没有捕获或忽略SIGALARM,您可能会终止您的进程。

正如所指出的,信号集函数非常轻量级,甚至可以作为宏来实现;您也可以只保留一个只包含
SIGALRM
的信号集,然后重新使用它


不管怎样,信号是否发生在
sigaddset()
sigeptyset()
调用期间实际上并不重要,
new\u集
old\u集
变量(可能)是线程本地的,并且在
sigprocmask()
返回之后才进入关键部分。

sigprocmask()是进入内核级别并实际更改信号屏蔽状态的唯一函数。其他函数只是在调用sigprocmask或将集合传递给另一个信号相关函数之前设置掩码的操纵函数。

“阻止信号并不意味着您的代码将是不可中断的。”是的,我的意思是通过我正在实现的上下文切换机制不可中断(更新的问题)。ualarm在每个线程\u时间\u片上关闭,处理程序将执行切换到另一个线程。