LV023-向进程发送信号
本文主要是进程通信——信号的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
一、向进程发送信号
Linux系统提供了kill()系统调用,一个进程可通过kill()向另一个进程发送信号;Linux系统还提供了库函数raise(),也可用于实现发送信号的功能。
1. kill()
1.1 函数说明
在linux下可以使用man 2 kill命令查看该函数的帮助手册。
c
/* 需包含的头文件 */
#include <sys/types.h>
#include <signal.h>
/* 函数声明 */
int kill(pid_t pid, int sig);【函数说明】该函数是一个系统调用,可将信号发送给指定的进程或进程组中的每一个进程。
【函数参数】
pid:pid_t类型,表示要发送信号给指定进程的PID号。参数pid为正数的情况下,用于指定接收此信号的进程pid;除此之外,参数pid也可设置为0或-1以及小于-1等值。pid 不同取值的含义如下:
| pid > 0 | 则信号sig将发送到pid指定的进程。 |
| pid = 0 | 则将sig发送到当前进程的进程组中的每个进程。 |
| pid = -1 | 则将sig发送到当前进程有权发送信号的每个进程,但进程1(init)除外。 |
| pid < -1 | 则将sig发送到ID为-pid的进程组中的每个进程。 |
【返回值】int类型,成功返回0,失败返回-1,并会设置errno。如果向一个不存在的进程发送信号,kill()将会返回-1,errno将被设置为ESRCH,表示进程不存在。
【使用格式】一般情况下基本使用格式如下:
c
/* 需要包含的头文件 */
#include <sys/types.h>
#include <signal.h>
/* 至少应该有的语句 */
kill(pid, sig);【注意事项】进程中将信号发送给另一个进程是需要权限的,并不是可以随便给任何一个进程发送信号,超级用户root进程可以将信号发送给任何进程,但对于非超级用户(普通用户)进程来说,其基本规则是发送者进程的实际用户ID或有效用户ID必须等于接收者进程的实际用户ID或有效用户ID。
1.2 使用实例
c
/* 头文件 */
#include <stdio.h> /* perror */
#include <signal.h> /* kill raise*/
#include <sys/types.h> /* getpid */
#include <unistd.h> /* sleep getpid */
/* 主函数 */
int main(int argc, char *argv[])
{
pid_t pid;
int sig;
printf("Please enter pid(this process pid is %d) and signal: ", getpid());
scanf("%d %d", &pid, &sig);
kill(pid, sig);
return 0;
}在终端执行以下命令编译程序:
shell
gcc test.c -Wall # 生成可执行文件 a.out
./a.out # 执行可执行程序然后,终端会打印提示信息,然后我们输入目标进程的PID和要发送的信号即可:
shell
Please enter pid(this process pid is 24683) and signal: 24683 11
段错误 (核心已转储)2. raise()
2.1 函数说明
在linux下可以使用man 3 raise命令查看该函数的帮助手册。
c
/* 需包含的头文件 */
#include <signal.h>
/* 函数声明 */
int raise(int sig);【函数说明】该函数可用于发送信号给自身,其实就等价于kill(getpid(), int sig);。
【函数参数】
sig:int类型,表示要发送给自身的信号。
【返回值】int类型,成功返回非0值,失败返回0。
【使用格式】一般情况下基本使用格式如下:
c
/* 需要包含的头文件 */
#include <sys/types.h>
#include <signal.h>
/* 至少应该有的语句 */
raise(sig);【注意事项】none
2.2 使用实例
c
/* 头文件 */
#include <stdio.h> /* perror */
#include <signal.h> /* kill raise*/
#include <sys/types.h> /* getpid */
#include <unistd.h> /* sleep getpid */
/* 主函数 */
int main(int argc, char *argv[])
{
int sig;
printf("Please enter signal: ");
scanf("%d", &sig);
raise(sig);
return 0;
}在终端执行以下命令编译程序:
shell
gcc test.c -Wall # 生成可执行文件 a.out
./a.out # 执行可执行程序然后,终端会打印提示信息,然后我们输入要发送的信号即可:
shell
Please enter signal: 7
总线错误 (核心已转储)