signal()信号-2-函数

一、函数描述

1. signal()

#include <signal.h>

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

signal()会将接收到的signum信号交给hander(可以是SIG_IGN, SIG_DFL)处理,signal()的功能会跟随着Unix版本的变化而变化。

当这个进程收到这个signum信号后,处理如下:

  ①如果handler是 SIG_IGN,此信号被忽略

  ②如果handler是 SIG_DFL,将由系统按默认的方法处理

  ③指定给handler函数来处理此信号。

返回值: signal()返回信号处理程序的前一个值,或者返回错误的SIG_ERR

注意:signal()在多线程进程中的影响是未指定的.

2. pause()

#include <unistd.h>
int pause(void);

pause()会导致调用进程(或线程)进入休眠状态,直到收到信号,此时会终止进程或引起信号捕获函数的调用。

pause() 仅在信号被捕获并且信号捕获函数返回时才返回。 在这种情况下,pause()返回-1,errno被设置为EINTR。

3. raise()

int raise(int sig);

raise()向调用进程或线程发送信号(本线程/进程)。在单线程进程中它等同于kill(getpid(), sig); 在多线程进程中它等同于 pthread_kill(pthread_self(), sig);
如果信号导致处理程序被调用,那么 raise() 在信号处理程序返回后才会返回,成功返回0

4. kill()

int kill(pid_t pid, int sig);

kill()将信号发送给进程,raise()只是向进程自身发送信号; kill()可用于将任何信号发送到任何进程组或进程5. 

5. alarm()

unsigned int alarm(unsigned int seconds);

alarm函数设置了一个定时器,当定时器到了就发送 SIGALRM 信号。

 

二、使用例子

1. signal()

复制代码
#include <stdio.h>
#include <signal.h>
 
void sig_handler(int sig) {
    printf("Caught signal %d\n", sig); //处理信号的逻辑
}
 
int main() {
    signal(SIGINT, sig_handler);  // 当用户按下Ctrl+C时,会触发SIGINT信号
    signal(SIGTERM, sig_handler); // 程序退出信号
    while(1) {
        // 主循环,程序会在此处阻塞,等待信号,或使用 pause() 等待信号
    }
    return 0;
}
复制代码

 

2. sigaction()

复制代码
#include <stdio.h>
#include <signal.h>
 
void sig_handler(int sig, siginfo_t *info, void *secret) {
    printf("Caught signal %d\n", sig); //处理信号的逻辑
}
 
int main() {
    struct sigaction sa;
    sa.sa_sigaction = &sig_handler;
    sa.sa_flags = SA_SIGINFO;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGTERM, &sa, NULL);
    while(1) {
        // 主循环,程序会在此处阻塞,等待信号
    }
    return 0;
}
复制代码

 

三、总结

1. 用户自定义信号 SIGUSR1(10) 和 SIGUSR2(12) 的使用,如 kill -10 <PID>

2. abort() 让进程捕捉 SIGABRT(6) 的意图是,在进程终止前由其执行所需的清理操作。

abort()首先开放 SIGABRT(6) 信号,然后向调用进程发送此信号。这将导致进程异常终止,除非 SIGABRT 信号被捕获且信号处理程序不返回。如果 abort() 函数导致进程终止,则所有打开的流将关闭并刷新。如果 SIGABRT 信号被忽略,或者被处理程序捕获,abort()函数仍将终止该进程。此函数是通过先恢复 SIGABRT 的缺省处置,然后再次产生此信号来完成此操作的。abort() 函数永远不会返回。

3. kill -l 列出所有信号;ctrl + c 产生SIGINT信号

4. select() poll() epoll() 都是基于信号的!

 

posted on   Hello-World3  阅读(1838)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示