当前位置:首页 > 系统教程 > 正文

Linux信号集操作函数详解从入门到实践,掌握信号集核心操作

Linux信号集操作函数详解从入门到实践,掌握信号集核心操作

Linux信号集操作函数详解从入门到实践,掌握信号集核心操作 Linux信号集操作函数  信号集函数用法 sigprocmask实例 信号屏蔽字设置 第1张

在Linux系统编程中,信号是一种重要的进程间通信和事件处理机制。而Linux信号集操作函数则是管理信号的核心工具,它们允许我们创建、修改和检查信号集,进而控制进程的信号屏蔽字。本文将从零开始,详细讲解这些函数的用法,即使是刚接触Linux编程的小白也能轻松跟上。

什么是信号集?

信号集(signal set)是一种数据结构,用于表示一组信号。在Linux中,它通常由sigset_t类型定义。我们可以把信号集想象成一个位图,每个信号对应一个位,1表示该信号在集中,0表示不在。通过信号集函数用法,我们可以方便地操作这个位图,而不必关心底层细节。

核心信号集操作函数详解

下面介绍五个最基本的信号集操作函数,它们都定义在中。

1. sigemptyset——清空信号集

    int sigemptyset(sigset_t *set);  

sigemptyset用于将指定的信号集初始化为空集,即所有信号对应的位清零。成功返回0,失败返回-1并设置errno。

2. sigfillset——填充所有信号

    int sigfillset(sigset_t *set);  

sigfillset将信号集填满,包含所有已定义的信号(不包括实时信号中未定义的)。通常用于一开始就想屏蔽所有信号的场景。

3. sigaddset——添加单个信号

    int sigaddset(sigset_t *set, int signum);  

向信号集中添加一个指定的信号,例如sigaddset(&set, SIGINT)将SIGINT加入集。

4. sigdelset——删除单个信号

    int sigdelset(sigset_t *set, int signum);  

从信号集中移除一个信号,与sigaddset相反。

5. sigismember——测试信号是否在集中

    int sigismember(const sigset_t *set, int signum);  

检查某个信号是否属于信号集。若在集内返回1,不在返回0,出错返回-1。

信号屏蔽字操作:sigprocmask

有了信号集,我们就可以用它来设置进程的信号屏蔽字。信号屏蔽字定义了当前阻塞哪些信号,即这些信号被递送到进程时将被挂起,直到解除屏蔽。sigprocmask函数就是用来查看或更改进程的信号屏蔽字的,是sigprocmask实例中的核心。

    int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);  
  • how:操作方式,取值:
    • SIG_BLOCK:将set中的信号添加到当前屏蔽字中(取并集)。
    • SIG_UNBLOCK:从当前屏蔽字中移除set中的信号。
    • SIG_SETMASK:直接将当前屏蔽字设置为set。
  • set:传入的信号集,若为NULL则忽略how,只用于获取当前屏蔽字。
  • oldset:如果不为NULL,返回旧的屏蔽字。

下面是一个简单的信号屏蔽字设置示例:

    #include #include #include int main() {    sigset_t newmask, oldmask;    sigemptyset(&newmask);    sigaddset(&newmask, SIGINT);  // 阻塞SIGINT (Ctrl+C)    // 设置新的屏蔽字,并保存旧的    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) == -1) {        perror("sigprocmask");        return 1;    }    printf("SIGINT 已被阻塞,请尝试按Ctrl+C,进程不会终止。");    sleep(5);    // 恢复旧的屏蔽字    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {        perror("sigprocmask restore");        return 1;    }    printf("SIGINT 已解除阻塞,再按Ctrl+C将终止进程。");    while(1);  // 等待信号    return 0;}  

检查挂起信号:sigpending

当信号被阻塞时,如果多次发生,内核会记录这些信号(但普通信号只记录一次)。sigpending函数可以获取当前进程的挂起信号集。

    int sigpending(sigset_t *set);  

成功时,set中会包含当前阻塞且正在等待递送的信号。结合前面的例子,我们可以在阻塞期间调用sigpending来查看是否有SIGINT被挂起。

总结

本文详细介绍了Linux信号集操作函数,包括sigemptysetsigfillsetsigaddsetsigdelsetsigismember,以及如何通过sigprocmask进行信号屏蔽字设置,并用sigpending检查挂起信号。通过sigprocmask实例的演示,相信大家已经掌握了这些信号集函数用法。在实际开发中,合理使用信号集可以避免竞态条件,实现精细的异步事件控制。

希望这篇教程对你有所帮助!如果有任何疑问,欢迎在评论区交流。