1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 int main() 5 { 6 while(1){ 7 sleep(1); 8 printf("---------\n"); 9 } 10 return 0; 11 }
ctrl + z: 发送一个停止信号, 让程序停止运行
进程并没有退出只是停止运行了
程序依然运行在后台;
kill: 给进程发送一个终止信号
进程退出
当使用Ctrl + z, 进程终止之后, 进程就不会再去处理信号了, 所以此时使用kill就不会杀死这个进程.
此时可以使用kill -9, 来杀死这个进程, kill -9 , 就是给进程发送9号命令.
int kill(pid_t pid, int sig);
给pid进程发送sig信号
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 #include<signal.h> 5 int main() 6 { 7 //kill(进程ID, 信号值) 8 kill(getpid(), SIGINT); 9 while(1){ 10 printf("-------\n"); 11 sleep(1); 12 } 13 return 0; 14 }
程序直接退出;
int raise(int sig);–给进程自身发送一个指定的信号
unsigned int alarm(unsidned int second);–sec秒之后给进程自身发送一个时钟信号–SIGALRM
void abort(void);–给进程自身发送一个SIGABRT信号
int sigqueue(pid_t pid, int sig, const union sigval value)
给一个进程发送信号的同时携带一个数据过去
注销:将信号信息进程pcb中移除(修改位图,删除节点)
非可靠:删除节点,修改位图为0
可靠:删除信号节点,检查链表中是否还有相同节点,没有则修改位图
处理:信号的处理也叫信号的递达,实际上就是打断进程当前的操作,去执行进程的对应信号处理函数
信号的处理方式:
1.默认处理方式
2.忽略处理方式
3.自定义处理方式–用户自己定义信号的处理回调函数
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);signum:信号值-表示要修改那个信号的处理方式
演示:
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 #include<signal.h> 5 int main() 6 { 7 //signal(信号, 处理方式) 8 signal(SIGINT, SIG_IGN); 9 //kill(进程ID, 信号值) 10 //kill(getpid(), SIGINT); 11 raise(SIGINT); 12 while(1){ 13 printf("-------\n"); 14 sleep(1); 15 } 16 return 0; 17 }
此时虽然调用raise但程序并未终止
因为调用signal将SIGINT信号忽略了;
只能使用Ctrl+\退出信号将进程退出
5 void sigcb(int signo) 6 { 7 printf("recv signal:%d\n", signo); 8 } 12 signal(SIGINT, sigcb);
Ctrl+c向进程发送一个2号信号
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
how:操作类型
SIG_BLOCK–阻塞set集合中的信号 block=block | set
SIG_UNBLOCK–将set集合中的信号解除阻塞block&=~set
SIG_SETMASK–将set集合中的信号设置为阻塞集合的信号block = set
返回值:成功返回0;失败返回-1;