Linux system programming 45 signals-kill() raise() alarm() pause()

kill()

man 2 kill

NAME
       kill - send signal to a process 

SYNOPSIS
       #include <sys/types.h>
       #include <signal.h>

       int kill(pid_t pid, int sig);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       kill(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE


DESCRIPTION
       The kill() system call can be used to send any signal to any process group or process.
pid>0  给指定进程发送信号
       If pid is positive, then signal sig is sent to the process with the ID specified by pid.

pid==0 组内广播,即给所有同组进程发送信号
       If pid equals 0, then sig is sent to every process in the process group of the calling process.

pid==-1   全局广播,给所有自己有权限发送信号的进程  发送信号,除init进程外,不包括init进程。一般就是init进程会发全局广播。
       If pid equals -1, then sig is sent to every process for which the calling process has permission to send signals, except for process 1 (init), but see below.

pid<-1 发送给指定进程组。将信号发送给 进程组ID绝对值 == pid绝对值的 进程组中的每个进程
       If pid is less than -1, then sig is sent to every process in the process group whose ID is -pid.

sig == 0  不会发送任何信号,用于检测一个进程或者进程组 是否存在。
       If sig is 0, then no signal is sent, but error checking is still performed; this can be used to check for the existence of a process ID or process group ID.

RETURN VALUE   0成功  -1失败
       On success (at least one signal was sent), zero is returned.  On error, -1 is returned, and errno is set appropriately.

ERRORS  如果失败,查看errno 如下:失败原因
       EINVAL An invalid signal was specified.  
		表示目标信号无效

       EPERM  The process does not have permission to send the signal to any of the target processes.
		表示 进程没有向任何目标进程发送信号的权限,即表示 目标进程或进程组存在,但是你没有发送信号的权限。

  	   ESRCH  The pid or process group does not exist.  Note that an existing process might be a zombie, a process which already committed termination, but has not yet been wait(2)ed for.
        pid或进程组不存在。注意,现有的进程可能是僵死进程,即已经提交了终止请求,但还没有被等待(2)的进程。

raise()

man 3 raise 标准库函数 



NAME
       raise - send a signal to the caller  给当前进程发送信号,自己给自己发信号

SYNOPSIS
       #include <signal.h>

       int raise(int sig);

DESCRIPTION
给当前进程或线程发送信号
       The raise() function sends a signal to the calling process or thread.  In a single-threaded program it is equivalent to

       kill(getpid(), sig); //给当前进程发送信号

   In a multithreaded program it is equivalent to

       pthread_kill(pthread_self(), sig);//给当前线程发送信号

   If the signal causes a handler to be called, raise() will return only after the signal handler has returned.

RETURN VALUE
       raise() returns 0 on success, and nonzero for failure.

alarm()

NAME
       alarm - set an alarm clock for delivery of a signal  设置一个发送信号的闹钟

SYNOPSIS
       #include <unistd.h>

       unsigned int alarm(unsigned int seconds);

DESCRIPTION
       alarm() arranges for a SIGALRM signal to be delivered to the calling process in seconds seconds.
       alarm()以秒为单位安排将一个SIGALRM信号发送给调用进程。 SIGALRM 也是终止信号

       If seconds is zero, any pending alarm is canceled.

       In any event any previously set alarm() is canceled.

RETURN VALUE
       alarm() returns the number of seconds remaining until any previously scheduled alarm was due to be delivered, or zero if there was no previously scheduled alarm.

Experiment 1: Basic usage of alarm

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

int main()
{
	alarm(5);

	while(1);

	exit(0);
}


mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ gcc alarm.c 
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ ./a.out 
Alarm clock
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$   延迟5秒

Experiment 2: The continuous setting of alarm has the most effective alarm

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

int main()
{
	alarm(5);
	alarm(10);
	alarm(1);

	while(1);

	exit(0);
}

mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ gcc alarm.c 
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ ./a.out 
Alarm clock
只延迟1秒
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$  

Experiment 3 signal + alarm

signal+ alarm 配合使用
 signal 一定要写在 alarm前面,如果alarm写在前面,如下:

       alarm(5);
       ... 中间程序 经过了5秒
signal(SIGALRM,alarm_handler);

In this case, the intermediate program has done more than 5 seconds of work, then after 5 seconds, when the signal comes, the program has not executed signal(), so you can’t see the new behavior of registering the signal: alarm_handler, then it will Follow the default behavior of this signal, which is to terminate the program.

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

static int loop = 1;

static void alarm_handler(int s)
{
	loop = 0;
}

int main()
{
	int64_t count = 0;

// signal 一定要写在 alarm前面
signal(SIGALRM,alarm_handler);
	alarm(5);
	
	while(loop)
		count++;

	printf("%ld\n",count);
	exit(0);
}



mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ gcc alarm.c 
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ time ./a.out 
2629709698

real	0m5.002s
user	0m4.936s
sys	0m0.000s
mhr@ubuntu:~/Desktop/xitongbiancheng/parallel/signal/test$ 

pause()

We specially made a blocking system call to be interrupted

NAME
       pause - wait for signal  等待一个信号,即人为做出来的一个阻塞的系统调用

SYNOPSIS
       #include <unistd.h>

       int pause(void);

pause() makes the calling process (or thread) dormant until the signal to terminate the process or call the signal capture function


In some environments, sleep() is encapsulated by alarm() + pause(). Some are encapsulated with nanosleep().

So sleep() is not recommended. The reason is that in an environment where sleep() is encapsulated by alarm() + pause(), when you use sleep() and alarm() at the same time in your program, an alarm must be covered. That is, one of alarm() and sleep() must fail.

Guess you like

Origin blog.csdn.net/LinuxArmbiggod/article/details/114024690
Recommended