1.1 kill
kill
函数是UNIX和类UNIX操作系统中的一个标准库函数,主要用于向指定进程发送信号。
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int signum);
pid_t pid
是进程ID,int signum
是信号的编号。
kill
函数的作用是将signum
指定的信号发送到pid
指定的进程。
-
pid > 0
:将信号发送给进程ID为pid
的进程。 -
pid = 0
:将信号发送给当前进程所在的整个进程组中的所有进程。 -
pid < 0
:将信号发送给进程组ID等于pid
的绝对值的进程组中的所有进程。 -
pid = -1
:将信号发送给系统中的所有进程,这个进程组号等于pid的绝对值。
kill
函数的成功返回值为0,失败返回值为-1
此外,调用kill
函数的进程必须有权限向目标进程发送信号。通常,只有root用户才能向所有进程发送信号,而非root用户只能向与自己用户ID相同的进程发送信号
案例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
int main()
{
pid_t pid;
pid = fork();
if(pid < 0)
{
perror("fail to fork");
exit(1);
}
else if(pid > 0) //父进程的代码区
{
while(1)
{
printf("This is parent peocess\n");
sleep(1);
}
}
else //子进程的代码区
{
printf("This is son process\n");
//子进程在3秒之后,让父进程退出
sleep(3);
//使用kill给父进程发送信号,然后父进程接收到信号后直接退出就可以了
kill(getppid(), SIGINT);
}
return 0;
}
执行结果
1.2 alarm函数
alarm
函数是UNIX和类UNIX系统中的一种标准库函数,它的主要作用是为当前进程设置一个定时器。
当设定时间到达后,定时器会向当前进程发送SIGALRM信号。
这个信号的默认行为是终止进程,但如果进程中有一个已注册的信号处理函数来处理SIGALRM信号,那么进程会根据该函数的逻辑来执行相应的操作
#include <sys/time.h>
unsigned int alarm(unsigned int seconds);
seconds
参数
指定了定时器的超时时间,单位是秒。
如果seconds
的值为0,那么之前设置的定时器会被取消,并且返回之前定时器剩余的时间。
如果seconds
的值为-1,那么返回的是0
alarm
函数的返回值有以下几种情况:
- 如果
seconds
的值为0,返回值也是0。 - 如果
seconds
的值大于0,并且在seconds
秒内再次调用了alarm
函数设置了新的定时器,那么返回值是之前定时器剩余的秒数。 - 如果
seconds
的值大于0,并且没有在seconds
秒内再次调用alarm
函数设置新的定时器,那么返回值是0
案例
#include <stdio.h>
#include <unistd.h>
#int main()
{
unsigned int sec;
//当执行到alarm之后,代码会接着往下执行,当设定的时间到后,会产生SIGALRM信
//如果alarm之前没有设置其他闹钟,则返回0,如果之前设置了,则返回之前剩余的
//如果一个程序中出现多个alarm闹钟,第一个如果没有到达指定的时间就遇到第二个
//则第一个的闹钟时间清除,按照第二个alarm闹钟的时间继续向下运行
sec = alarm(5);
printf("sec = %d\n", sec);
sleep(3);
sec = alarm(6);
printf("sec = %d\n", sec);
while(1)
{
printf("hello world\n");
sleep(1);
}
return 0;
}
执行结果
1.3 raise函数
raise
函数主要用于向当前进程发送一个信号。这个函数的原型如下:
#include <signal.h>
int raise(int sig);
sig
参数是你想要发送的信号的名字
。这个函数的工作原理是,当你调用raise
函数并传入一个特定的信号名时,它会向当前进程发送这个信号
返回值: 成功:0
失败:非0
raise(sig) 等同于 kill(getpid(), sig)
案例
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char const *argv[])
{
int num = 0;
while(1)
{
printf("hello world\n");
sleep(1);
num++;
//当循环执行5秒后,进程退出
if(num == 5)
{
//使用raise给当前进程本身发送信号
raise(SIGALRM);
//等同于kill(getpid(), SIGALRM);
}
}
return 0;
}
执行结果
1.4 abort函数
abort
函数是C语言中的一个标准库函数,其原型定义在<stdlib.h>
头文件中。
该函数的主要作用是使当前的进程异常终止,即立即停止当前正在执行的程序,而不进行正常的资源回收和清理工作。
#include <stdlib.h>
void abort(void);
功能:向进程发送一个SIGABRT信号,默认情况下进程会退出。
参数:无
返回值:无
注意: 即使SIGABRT信号被加入阻塞集,一旦进程调用了abort函数,进程也还是会被终止, 且在终止前会刷新缓冲区,关闭文件描述符。
案例
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
int num = 0;
while(1)
{
printf("hello world\n");
sleep(1);
num++;
//当循环执行5秒后,进程退出
if(num == 5)
{
abort();
}
}
return 0;
}
执行结果
1.5 pause函数
pause
函数作用是使当前进程进入等待状态,直到接收到一个信号为止。
这个函数通常用于等待某个特定的事件发生,例如等待用户输入或者等待某个条件满足。
#include <sys/wait.h>
int pause(void);
返回值: 当有信号产生时,函数返回‐1
案例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
int main()
{
pid_t pid;
pid = fork();
if(pid < 0)
{
perror("fail to fork");
exit(1);
}
else if(pid > 0) //父进程的代码区
{
printf("This is parent peocess\n");
//使用pause阻塞等待捕捉信号
pause();
}
else //子进程的代码区
{
printf("This is son process\n");
sleep(3);
kill(getppid(), SIGINT);//睡眠三秒后杀死父进程
}
return 0;
}
执行结果
1.6 signal函数
signal
函数是用于设置一个特定的信号处理函数的标准库函数。
当进程接收到一个信号时,signal
函数允许你指定一个函数来处理这个信号。
#include <signal.h>
void (*signal(int sig, void (*func)(int)))(int);
‐‐>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
功能:当进程中产生某一个信号时,对当前信号进行处理
参数:
sig:指定要处理的信号
handler:处理方式
SIG_IGN 当信号产生时,以缺省(忽略)的方式处理
SIG_DFL 当信号产生时,以当前信号默认的方式处理
func
是你想要设置的信号处理函数。信号处理函数必须具有以下形式
void func(int sig);
当信号产生时,通过信号处理函数自定义方式处理,函数名可以随便写,参数表示当前的信号
返回值: 成功:返回函数地址,该地址为此信号上一次注册的信号处理函数的地址
失败:SIG_ERR文章来源:https://www.toymoban.com/news/detail-856351.html
1.6.1 signal函数的使用
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
void handler(int sig);
int main(int argc, char const *argv[])
{
//以默认的方式处理信号
#if 0
if(signal(SIGINT, SIG_DFL) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
if(signal(SIGQUIT, SIG_DFL) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
if(signal(SIGTSTP, SIG_DFL) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
#endif
//以忽略的方式来处理信号
#if 0
if(signal(SIGINT, SIG_IGN) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
if(signal(SIGQUIT, SIG_IGN) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
if(signal(SIGTSTP, SIG_IGN) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
//注意:SIGKILL和SIGSTOP这两个信号只能以默认的方式处理,不能忽略或者捕捉
// if(signal(SIGKILL, SIG_IGN) == SIG_ERR)
// {
// perror("fail to signal");
// exit(1);
// }
#endif
//以用户自定义方式处理信号
#if 1
if(signal(SIGINT, handler) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
if(signal(SIGQUIT, handler) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
if(signal(SIGTSTP, handler) == SIG_ERR)
{
perror("fail to signal");
exit(1);
}
#endif
while(1)
{
printf("hello world\n");
sleep(1);
}
return 0;
}
void handler(int sig)
{
if(sig == SIGINT)
{
printf("SIGINT正在处理\n");
}
if(sig == SIGQUIT)
{
printf("SIGQUIT正在处理\n");
}
if(sig == SIGTSTP)
{
printf("SIGTSTP正在处理\n");
}
}
在使用signal
函数时,还需要考虑信号处理的同步和互斥问题,以确保程序的正确性和稳定性文章来源地址https://www.toymoban.com/news/detail-856351.html
到了这里,关于kill,alarm,raise,abort,pause,signal等函数的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!