现在位置: 首页 > C 教程 > 正文

C 库函数 - sigsuspend()

C 标准库 - <signal.h> C 标准库 - <signal.h>

sigsuspend 函数是 C 标准库中的一个函数,用于临时替换当前的信号屏蔽字并挂起进程,直到捕捉到一个信号。它常用于实现原子信号等待,即在等待信号时不会丢失任何信号。

语法

int sigsuspend(const sigset_t *mask);

参数

  • const sigset_t *mask:指向新的信号屏蔽字的指针。sigsuspend 使用该信号屏蔽字替换当前信号屏蔽字,并在捕捉到一个信号后恢复原来的信号屏蔽字。

返回值

  • sigsuspend 函数总是返回 -1,并将 errno 设置为 EINTR,表示函数因信号中断。

实例

以下是一个使用 sigsuspend 函数等待特定信号的示例程序。该程序设置一个信号处理程序,然后使用 sigsuspend 挂起进程直到捕捉到信号。

实例

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

volatile sig_atomic_t flag = 0;

// 自定义的信号处理函数
void handle_sigint(int sig) {
    printf("Caught signal %d\n", sig);
    flag = 1;
}

int main() {
    struct sigaction sa;
    sigset_t new_mask, old_mask, wait_mask;

    // 设置 SIGINT 的处理程序为 handle_sigint
    sa.sa_handler = handle_sigint;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGINT, &sa, NULL) == -1) {
        perror("sigaction");
        return 1;
    }

    // 初始化信号集
    sigemptyset(&new_mask);
    sigaddset(&new_mask, SIGINT);

    // 阻塞 SIGINT 信号
    if (sigprocmask(SIG_BLOCK, &new_mask, &old_mask) == -1) {
        perror("sigprocmask");
        return 1;
    }

    // 初始化等待信号集
    sigemptyset(&wait_mask);

    printf("Waiting for SIGINT...\n");

    // 使用 sigsuspend 挂起进程,等待信号
    while (!flag) {
        if (sigsuspend(&wait_mask) != -1) {
            perror("sigsuspend");
            return 1;
        }
    }

    // 恢复原来的信号屏蔽字
    if (sigprocmask(SIG_SETMASK, &old_mask, NULL) == -1) {
        perror("sigprocmask");
        return 1;
    }

    printf("Exiting...\n");

    return 0;
}

假设编译并运行程序后,输出将是:

Waiting for SIGINT...

当按下 Ctrl+C(发送 SIGINT 信号)时,输出将是:

Caught signal 2
Exiting...

程序捕捉到 SIGINT 信号,执行了信号处理函数 handle_sigint,设置 flag 为 1,使得主循环终止并退出程序。

解释

  • sigset_t new_mask, old_mask, wait_mask;:定义了三个信号集,用于控制信号屏蔽。
  • 使用 sigprocmask 函数阻塞 SIGINT 信号,并保存原来的信号屏蔽字。
  • 使用 sigsuspend 函数挂起进程,等待信号。sigsuspend 临时替换当前的信号屏蔽字为 wait_mask,并在捕捉到信号后恢复原来的信号屏蔽字。
  • 在捕捉到信号后,恢复原来的信号屏蔽字,并继续执行程序。

注意事项

  • sigsuspend 常用于实现可靠的信号等待机制,避免信号在屏蔽期间丢失。
  • 信号处理函数应尽量简短,因为在处理信号时会阻塞其他信号。长时间运行的信号处理函数可能会影响程序的实时性。

C 标准库 - <signal.h> C 标准库 - <signal.h>