Linux环境编程第五天笔记

Linux环境编程第五天笔记

kill和kill()

kill 是一个发送信号的系统调用,也是是终止进程的命令。

返回值:成功:返回0;失败:返回-1;

复制代码
 #include <sys/types.h>
 #include <signal.h>
 ​
 int kill(pid_t pid, int sig);
pid 值 含义
> 0 发送给指定PID的进程
= 0 发送给与调用进程同进程组的所有进程
= -1 发送给有权限发送的所有进程(除了init进程)
< -1 发送给进程组ID等于 |pid| 的所有进程

sig 参数:信号编号

常用信号 编号 默认动作 说明
SIGTERM 15 终止 优雅终止(可捕获处理)
SIGKILL 9 终止 强制终止(不可捕获、不可忽略)
SIGINT 2 终止 终端中断(Ctrl+C)
SIGSTOP 19 停止 暂停进程(不可捕获)
SIGCONT 18 继续 继续被暂停的进程
SIGUSR1 10 终止 用户自定义信号1
SIGUSR2 12 终止 用户自定义信号2
SIGHUP 1 终止 终端挂断
kill命令常用用法
复制代码
 命令格式                            功能说明
 kill -l                         查看系统所有的信号
 kill -s SIGINT 3115             给PID为3115的进程发送SIGINT信号(使用的是信号名)
 kill -2 3124                    给PID为3124的进程发送2号信号(使用的是信号的值)
 killall -s SIGINT a.out         给所有名为a.out的进程发送SIGINT信号
 killall -2 a.out                给所有名为a.out的进程发送2号信号
signal()

接收一个信号

返回值:成功:返回最近一次调用时参数二的值;失败:返回SIG_ERR

复制代码
 #include <signal.h>
 ​
 void (*signal(int sig, void (*func)(int)))(int);
 ​
 typedef void (*sighandler_t)(int);
 sighandler_t signal(int signum, sighandler_t handler);
  • signum:要接收的信号

  • handler:

    • SIG_IGN:忽略该信号。

    • SIG_DEF:执行缺省动作

    • void(*p):执行p指向的信号响应函数

raise()

给自己发送一个信号

返回值:成功:返回0;失败:返回非0

复制代码
 #include <signal.h>
 ​
 int raise(int sig);
pause()

将本进程挂起,直到收到一个信号

返回值:收到非致命信号返回-1;收到致命信号不返回

复制代码
 #include <unistd.h>
 ​
 int pause(void);
信号集操作函数

返回值:成功:sigismember返回1,其余返回0;失败:sigismember返回0,其余返回-1;

复制代码
 #include <signal.h>
 ​
 int sigemptyset(sigset_t *set); //将信号集清空
 int sigfillset(sigset_t *set);  //将所有信号添加到信号集中
 int sigaddset(sigset_t *set,int signum);  //将指定一个信号加入到信号集中
 int  sigdelset(sigset_t *set,int signum);//将指定一个信号从信号集中剔除
 int sigismember(sigset_t *set,int signum); //判断一个指定的信号是否被信号集包含
  • set :信号集

  • signum :要操作的信号

SIGKILL和SIGSTOP是两个特殊的信号,不可被忽略,不可被阻塞,不可被捕捉

sigprocmask()

阻塞或解除阻塞一个或多个信号

返回值:成功:返回0;失败:返回-1;

复制代码
 #include <signal.h>
 ​
 int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
  • how :

    • SIG_BLOCK :将set中信号添加到当前阻塞信号集中

    • SIG_UNBLOCK :从当前信号集中移除set中的信号

    • SIG_SETMASK :把原有的阻塞信号集替换为当前的信号集

  • set :指向信号集的指针,如果为NULL,则how参数会被忽略

  • oldset :原有信号集,如果对原有信号集不感兴趣,可以设置为NULL

sigqueue()

向某进程发送一个指定数据,类似于kill,区别是sigqueue可以处理携带额外数据的信号。

返回值:成功:返回0;失败:返回-1

复制代码
 #include <signal.h>
 ​
 int sigqueue(pid_t pid, int sig, const union sigval value);
  • pid :目标进程的PID

  • sig :要发送的信号

  • value :携带的额外数据

复制代码
 union sigval {
     int   sival_int;  // 传递整数
     void *sival_ptr;  // 传递指针(注意:跨进程传递指针通常无效,因为地址空间独立)
 };              
sigaction()

捕捉一个指定信号,且可以通过扩展函数获得信号携带的额外数据

返回值:成功:返回0;失败:返回-1;

复制代码
 #include <signal.h>
 ​
 int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact);
  • sig :要捕捉的信号

  • act :NULL 时:仅查询当前处理方式;非 NULL 时:设置该信号的新处理方式;

复制代码
 struct sigaction 
 {   
     void (*sa_handler)(int);    // 普通处理函数(无附加数据) 
     void (*sa_sigaction)(int, siginfo_t *, void *);  //高级处理函数(可接收信号附带的数据) 
     sigset_t sa_mask;   // 信号掩码:处理该信号时,临时阻塞这些信号   
     int sa_flags;    // 标志位:控制信号处理的行为(核心)
     void (*sa_restorer)(void);    // 已废弃 
 }

高级处理函数参数

复制代码
 //siginfo_t 结构体
 typedef struct siginfo {
     int          si_signo;    // 1. 收到的信号编号(如 SIGUSR1=10)
     int          si_errno;    // 2. 错误码(一般为 0,仅特殊信号有值)
     int          si_code;     // 3. 信号产生的原因(如发送者是进程/内核)
     pid_t        si_pid;      // 4. 发送信号的进程 PID(跨进程通信常用)
     uid_t        si_uid;      // 5. 发送信号的进程所属用户 ID
     union sigval si_value;    // 6. 核心:信号附带的附加数据(就是你说的“数据+指针”联合体)
     // 其他额外字段(针对特定信号,如 SIGSEGV 会有内存错误地址等,日常用得少)
 } siginfo_t;

举例:

复制代码
 #include <stdio.h>
 #include <signal.h>
 ​
 void sig_handler(int signo, siginfo_t *info, void *context) {
     printf("收到信号:%d\n", signo);
     printf("发送信号的进程ID:%d\n", info->si_pid);
 }
 ​
 int main() {
     struct sigaction act;
     // 初始化清空结构体
     sigemptyset(&act.sa_mask);
     // 启用扩展信号处理模式
     act.sa_flags = SA_SIGINFO;
     // 指定扩展处理函数
     act.sa_sigaction = sig_handler;
 ​
     // 为SIGUSR1信号设置处理方式
     sigaction(SIGUSR1, &act, NULL);
 ​
     // 等待信号
     while(1);
     return 0;
 }

act.sa_sigaction只绑定函数指针,而函数指针的参数需要使用sigqueue()进行单独传递

sa_flags可选参数
SA_SIGINFO 使用扩展信号响应函数
SA_RESTART 自动重启被信号中断的某些系统调用
SA_NOCLDSTOP 对于SIGCHLD信号,子进程暂停/恢复不提醒(不发送SIGCHLD)
SA_NOCLDWAIT 对于SIGCHLD信号,子进程终止后,系统自动回收僵尸进程
SA_NODEFER 在处理当前信号时,不自动阻塞该信号本身(当信号处理函数执行时,内核会阻塞信号本身)
SA_ONSTACK 使用预先设置的替代信号栈执行执行信号处理函数,不使用进栈主栈
SA_RESETHAND 信号处理函数执行一次之后,自动恢复该信号的默认处理方式
  • oldact :NULL 时:不保存;非 NULL 时:保存该信号原来的处理方式,方便后续恢复;
atoi

atoi 是 C 标准库<stdlib.h>中的一个函数,作用是把字符串形式的数字转换成整数,成功返回转换后的数字,失败返回0。

相关推荐
Gain_chance2 小时前
32-学习笔记尚硅谷数仓搭建-DWD层首日数据装载脚本及每日数据装载脚本
大数据·数据仓库·hive·笔记·学习
firstacui2 小时前
搭建harbor仓库
linux·docker
niceffking2 小时前
Linux信号相关函数
linux·运维·服务器·linux信号
蚰蜒螟2 小时前
Linux 7 中的系统调用原理
linux·运维·服务器
Reuuse2 小时前
【linux】进程间通信
linux·运维·服务器
学海无涯书山有路2 小时前
泛型笔记问答
笔记
code monkey.2 小时前
【Linux之旅】Linux 动静态库与 ELF 加载全解析:从制作到底层原理
linux·服务器·c++·动静态库
Pluto_CSND2 小时前
CentOS系统中创建定时器
linux·运维·centos
好好沉淀2 小时前
Docker 部署 Kibana:查 ES 版本 + 版本匹配 + 中文界面
linux·docker