linux多进程——进程组与会话、守护进程、信号通信 .
来源:互联网 发布:舒耐止汗喷雾危害 知乎 编辑:程序博客网 时间:2024/05/17 02:56
- killraise 发信号一些相关知识可以参考 Linux 信号通信
- pause 将进程挂起直到捕捉到信号为止
- 举例1
进程组:是一个或多个进程的集合。可以调用 getpgid(0) 或 getpgrp() 来得到。进程组ID为组长的进程ID。只要进程组中有一个进程存在,进程组就存在,与组长进程是否终止无关。调用 setpgid() 加入一个现有的进程组或创建一个新的进程组。
会话:一个或多个进程组的集合
可以用 setsid() 建立新会话,则该进程会变成新会话的首进程,同时成为一个新进程组的组长进程,该进程没有控制终端。
二、守护进程
守护进程的特点:没有终端的限制,不受用户、终端或其它的变化而受到影响。
创建守护进程的步骤:
出错处理:因为守护进程不依赖于终端,所以出错信息是不能用 printf 滴,这..... 怎么办?莫怕,用 syslog() 就能搞定~
用系统日志就要调用三个函数:openlog()、syslog()、closelog() 系统日志存于 /var/log/messages
举例:
- #include<stdio.h>
- #include<stdlib.h>
- #include<sys/types.h>
- #include<syslog.h>
- int main(){
- pid_t pid,s;
- int i;
- char *buff="Daemon Test!\n";
- if((pid = fork())<0){
- printf("fork error!\n");
- exit(1);
- }else if(pid> 0){
- exit(0);
- }
- //第一个参数为在消息之前加入的字符串,第二个参数在每个消息中包含进程的ID,第三个参数指定程序发送的消息类型
- openlog("daemon_testlog",LOG_PID,LOG_DAEMON);
- if((s=setsid())<0){
- //第一个参数为参数类型,第二个参数为信息字符串
- syslog(LOG_ERR,"%s\n","setsid error!");
- }
- chdir("/");
- umask(0);
- for(i=0;i<getdtablesize();i++){ //关闭文件描述
- close(i);
- }
- while(1){
- syslog(LOG_INFO,"%s\n",buff);
- sleep(10);
- }
- closelog();
- return 0;
- }
#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<syslog.h>int main(){ pid_t pid,s; int i; char *buff="Daemon Test!\n"; if((pid = fork())<0){ printf("fork error!\n"); exit(1); }else if(pid> 0){ exit(0); } //第一个参数为在消息之前加入的字符串,第二个参数在每个消息中包含进程的ID,第三个参数指定程序发送的消息类型 openlog("daemon_testlog",LOG_PID,LOG_DAEMON); if((s=setsid())<0){ //第一个参数为参数类型,第二个参数为信息字符串 syslog(LOG_ERR,"%s\n","setsid error!"); } chdir("/"); umask(0); for(i=0;i<getdtablesize();i++){ //关闭文件描述 close(i); } while(1){ syslog(LOG_INFO,"%s\n",buff); sleep(10); } closelog(); return 0;}
三、信号
Linux对每种信号都制定了默认的操作。捕捉到信号可以采用默认的操作、可以忽略(SIGKILL 与 SIGSTOP除外)、也可以执行相应的自定义处理函数。
kill()、raise() 发信号。一些相关知识可以参考Linux 信号通信
pause() 将进程挂起直到捕捉到信号为止。
举例1:
- #include <stdio.h>
- #include <stdlib.h>
- #include <signal.h>
- void my_func(int);
- int main() {
- printf("Wainting for signal: SIGINT/SIGQUIT...\n");
- signal(SIGINT,my_func);
- signal(SIGQUIT,my_func);
- pause();
- pause();
- exit(0);
- }
- void my_func(int sign_no){
- if (sign_no==SIGINT) {
- printf("I got CTRL+C!\n");
- } else if (sign_no==SIGQUIT) {
- printf("I got CTRL+\\!\n");
- }
- }
#include <stdio.h>#include <stdlib.h>#include <signal.h>void my_func(int);int main() {printf("Wainting for signal: SIGINT/SIGQUIT...\n");signal(SIGINT,my_func);signal(SIGQUIT,my_func);pause();pause();exit(0);}void my_func(int sign_no){if (sign_no==SIGINT) {printf("I got CTRL+C!\n");} else if (sign_no==SIGQUIT) {printf("I got CTRL+\\!\n");} }举例2:
- #include<stdio.h>
- #include<stdlib.h>
- #include<sys/types.h>
- #include<signal.h>
- int main(){
- pid_t pid;
- if((pid = fork())<0){
- printf("fork error!\n");
- exit(1);
- }else if(pid == 0){
- printf("Child process wait for singal....a\n");
- raise(SIGSTOP); //子进程向自己发送一个消息,线程停止
- printf("Child is dead\n"); //此句不会打出来,因为进程直接被kill了
- }else{
- sleep(10);
- kill(pid,SIGKILL);
- wait(NULL);
- }
- return 0;
- }
#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<signal.h>int main(){ pid_t pid; if((pid = fork())<0){ printf("fork error!\n"); exit(1); }else if(pid == 0){ printf("Child process wait for singal....a\n"); raise(SIGSTOP); //子进程向自己发送一个消息,线程停止 printf("Child is dead\n"); //此句不会打出来,因为进程直接被kill了 }else{ sleep(10); kill(pid,SIGKILL); wait(NULL); } return 0;}
alarm() 在进程中设置一个定时器,当时间到时,发出SIGALARM信号。一个进程只能有一个闹钟时间,新的将代替旧的。返回值为新旧时间差值。
举例:
- #include<stdio.h>
- #include<stdlib.h>
- #include<sys/types.h>
- #include<signal.h>
- int main(){
- int ret=alarm(5);
- printf("alarm...%d\n",ret);
- sleep(3);
- ret=alarm(5);
- printf("alarm...%d\n",ret);
- pause();
- printf("never show\n");
- }
#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<signal.h>int main(){ int ret=alarm(5); printf("alarm...%d\n",ret); sleep(3); ret=alarm(5); printf("alarm...%d\n",ret); pause(); printf("never show\n");}
程序运行结果为:alarm...0 alarm....2 。 2为相差时间,程序收到SIGALARM默认执行的操作为终止线程。
sigaction()函数:signal()的高级版~
例子:
- #include<stdio.h>
- #include<stdlib.h>
- #include<sys/types.h>
- #include<signal.h>
- void my_func(int);
- int main(){
- struct sigaction sa,oldsa;
- printf("waiting for SIGINT/SIGQUIT......\n");
- sa.sa_handler=my_func; //设定处理函数
- sigemptyset(&sa.sa_mask); //清空信号集合
- sa.sa_flags=0; //对信号处理的选项一般设为0
- sigaction(SIGINT,&sa,&oldsa); //oldsa为保存旧的信号结构体
- sigaction(SIGQUIT,&sa,&oldsa);
- pause();
- pause();
- pause();
- pause();
- pause();
- pause();
- pause();
- }
- void my_func(int sig){
- if(sig == SIGINT){
- printf("Receive CTRL+C!\n");
- }
- else if(sig == SIGQUIT){
- printf("Receive CTRL+\\!\n");
- }else
- printf("Receive Signal!\n");
- }
#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<signal.h>void my_func(int);int main(){ struct sigaction sa,oldsa; printf("waiting for SIGINT/SIGQUIT......\n"); sa.sa_handler=my_func; //设定处理函数 sigemptyset(&sa.sa_mask); //清空信号集合 sa.sa_flags=0; //对信号处理的选项一般设为0 sigaction(SIGINT,&sa,&oldsa); //oldsa为保存旧的信号结构体 sigaction(SIGQUIT,&sa,&oldsa); pause(); pause(); pause(); pause(); pause(); pause(); pause();}void my_func(int sig){ if(sig == SIGINT){ printf("Receive CTRL+C!\n"); } else if(sig == SIGQUIT){ printf("Receive CTRL+\\!\n"); }else printf("Receive Signal!\n");}
信号集
通常就是这个步骤。清空信号集->添加信号->设置信号屏蔽->定义信号处理
举例:
- #include <stdio.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <unistd.h>
- void my_func(int);
- int main() {
- struct sigaction sa1,sa2;
- sigset_t set;
- //清空
- if (sigemptyset(&set)<0) {
- perror("sigemptyset");
- exit(1);
- }
- //添加信号
- if (sigaddset(&set,SIGINT)<0) {
- perror("sigaddset SIGINT");
- exit(1);
- }
- if (sigaddset(&set,SIGQUIT)<0) {
- perror("sigaddset SIGQUIT");
- exit(1);
- }
- //设置信号
- if (sigismember(&set,SIGINT)) {
- sa1.sa_handler=my_func;
- sigemptyset(&sa1.sa_mask);
- sa1.sa_flags=0;
- sigaction(SIGINT,&sa1,NULL);
- }
- if (sigismember(&set,SIGQUIT)) {
- sa2.sa_handler=SIG_DFL;
- sigemptyset(&sa2.sa_mask);
- sa2.sa_flags=0;
- sigaction(SIGQUIT,&sa2,NULL);
- }
- //设置屏蔽字
- if (sigprocmask(SIG_BLOCK,&set,NULL)<0) {
- perror("sigprocmask");
- exit(1);
- } else {
- printf("Signal set is blocked!\n");
- }
- while(1){
- int c=getchar();
- if ((c=='u')||(c=='U'))
- break;
- }
- //解除屏蔽字
- if (sigprocmask(SIG_UNBLOCK,&set,NULL)<0) {
- perror("sigprocmask");
- exit(1);
- } else {
- printf("Signal set is unblocked!\n");
- }
- }
- void my_func(int sig){
- if(sig == SIGINT){
- printf("Receive CTRL+C!\n");
- }
- else if(sig == SIGQUIT){
- printf("Receive CTRL+\\!\n");
- }else
- printf("Receive signal!\n");
- }
#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <sys/types.h>#include <unistd.h>void my_func(int);int main() { struct sigaction sa1,sa2; sigset_t set; //清空 if (sigemptyset(&set)<0) {perror("sigemptyset");exit(1); } //添加信号 if (sigaddset(&set,SIGINT)<0) {perror("sigaddset SIGINT");exit(1); } if (sigaddset(&set,SIGQUIT)<0) {perror("sigaddset SIGQUIT");exit(1); } //设置信号 if (sigismember(&set,SIGINT)) {sa1.sa_handler=my_func;sigemptyset(&sa1.sa_mask);sa1.sa_flags=0;sigaction(SIGINT,&sa1,NULL); } if (sigismember(&set,SIGQUIT)) {sa2.sa_handler=SIG_DFL;sigemptyset(&sa2.sa_mask);sa2.sa_flags=0;sigaction(SIGQUIT,&sa2,NULL); } //设置屏蔽字 if (sigprocmask(SIG_BLOCK,&set,NULL)<0) {perror("sigprocmask");exit(1); } else {printf("Signal set is blocked!\n"); } while(1){ int c=getchar();if ((c=='u')||(c=='U'))break; } //解除屏蔽字 if (sigprocmask(SIG_UNBLOCK,&set,NULL)<0) {perror("sigprocmask");exit(1); } else {printf("Signal set is unblocked!\n"); }}void my_func(int sig){ if(sig == SIGINT){ printf("Receive CTRL+C!\n"); } else if(sig == SIGQUIT){ printf("Receive CTRL+\\!\n"); }else printf("Receive signal!\n");}
[注] 1、解锁的瞬间即调用处理函数。2、内核只会保存一个同类的信号,其他的都被丢掉了。
- linux多进程——进程组与会话、守护进程、信号通信
- linux多进程——进程组与会话、守护进程、信号通信
- linux多进程——进程组与会话、守护进程、信号通信 .
- Linux 的进程组、会话、守护进程
- Linux--进程组、会话、守护进程
- Linux 的进程组、会话、守护进程
- linux进程组、会话和守护进程
- Linux--进程组、会话、守护进程
- Linux--进程组、会话、守护进程
- Linux--进程组、会话、守护进程
- Linux--进程组、会话、守护进程
- Linux--进程组、会话、守护进程
- Linux--进程组、会话、守护进程
- Linux--进程组、会话、守护进程
- Linux--进程组、会话、守护进程
- Linux--进程组、会话、守护进程
- Linux--进程组、会话、守护进程
- linux会话期,进程组,守护进程
- IE和firefox主要前端兼容性问题
- hdu2191
- 打开特定的app下载以及评论的appstore页面
- nodeJS入门例子一—工具(util)
- UML2.0合成结构图简单说明与范例
- linux多进程——进程组与会话、守护进程、信号通信 .
- 不能断点调试引用的项目的问题解决
- 常见Android屏幕分辨率以及对应机型
- nodeJS入门例子一—插件(Addons)
- cocos2d-x 菜鸟实习生学习篇
- 关于jbpm4.4的el的问题
- 在 CentOS 6.0 64bit 上搭建Sphinx环境
- JAVA面向对象笔记总结(上)
- nodeJS入门例子一—模块(Modules)