手机在线做ppt的网站,企装网怎么样,怎么导入文章到wordpress,怎么开发平台软件进程组#xff1a;一个或多个进程的集合#xff0c;进程组id是一个正整数。组长进程#xff1a;进程组id 进程id组长进程可以创建一个进程组#xff0c;创建该进程组的进程#xff0c;终止了#xff0c;只要进程组有一个进程存在#xff0c;进程组就存在#xff0c;与…进程组一个或多个进程的集合进程组id是一个正整数。组长进程进程组id 进程id组长进程可以创建一个进程组创建该进程组的进程终止了只要进程组有一个进程存在进程组就存在与组长进程是否终止无关。进程组生存期进程组创建到最后一个进程离开终止或转移到另一个进程组一个进程可以为自己或子进程设置进程组id作用子进程退出时不管父子进程同不同一个进程组都会发SIGCHLD信号给父进程当父子进程同进程组时父进程应捕捉SIGCHLD信号对子进程资源进程回收防止僵尸进程的产生当父子进程不同进程组时比如设置子进程成为了一个新的进程组这时候子进程退出系统也会正常回收子进程的资源不会产生僵尸进程的相关函数#include unistd.hint setpgid(pid_t pid, pid_t pgid); //pid 0, pgid 0,让当前进程成为一个进程组并且进程组id为当前进程的pidpid_t getpgid(pid_t pid); //pid 0,获取当前进程的进程组idpid_t getpgrp(void); /* POSIX.1 version */pid_t getpgrp(pid_t pid); /* BSD version */int setpgrp(void); /* System V version */int setpgrp(pid_t pid, pid_t pgid); /* BSD version */demo父子进程同一个进程组#include stdio.h
#include unistd.h
#include stdlib.h
#include signal.h
#include sys/types.h
#include sys/wait.hvoid do_sigchld(int signo)
{pid_t pid;int status;printf(signo %d\n, signo);while((pid waitpid(0, status, WNOHANG)) 0) // 0:跟调用进程同组的子进程WNOHANG不阻塞立即返回{if (WIFEXITED(status))printf(child %d exit status %d\n, pid, WEXITSTATUS(status));else if (WIFSIGNALED(status))printf(chid %d exit by signal %d\n, pid, WTERMSIG(status));}
}int main(int argc, char *argv[])
{pid_t pid;//阻塞SIGCHLD信号sigset_t set;sigemptyset(set);sigaddset(set, SIGCHLD);sigprocmask(SIG_BLOCK, set, NULL);pid fork();if (pid 0){//in child//解除阻塞SIGCHLD信号sigprocmask(SIG_UNBLOCK, set, NULL);//进程组printf(child pid %d, process group id getpgid(0) %d\n, getpid(), getpgid(0));printf(child pid %d, process group id getpgid(getpid()) %d\n, getpid(), getpgid(getpid()));printf(child pid %d, process group id getpgrp() %d\n, getpid(), getpgrp());/*setpgid(0, 0); //pid 0, pgid 0,让当前进程成为一个进程组并且进程组id为当前进程的pidprintf(after setpgid(0, 0) child pid %d, process group id getpgid(0) %d\n, getpid(), getpgid(0));printf(after setpgid(0, 0) child pid %d, process group id getpgid(getpid()) %d\n, getpid(), getpgid(getpid()));printf(after setpgid(0, 0) child pid %d, process group id getpgrp() %d\n, getpid(), getpgrp());*/}else if (pid 0){//in parent//先捕捉SIGCHLD信号struct sigaction act;act.sa_handler do_sigchld;sigemptyset(act.sa_mask);act.sa_flags 0; //0:用sa_handler参数SA_SIGINFO:用sa_sigaction参数sigaction(SIGCHLD, act, NULL);//再解除阻塞SIGCHLD信号sigprocmask(SIG_UNBLOCK, set, NULL);//进程组printf(parent pid %d, process group id getpgid(0) %d\n, getpid(), getpgid(0));printf(parent pid %d, process group id getpgid(getpid()) %d\n, getpid(), getpgid(getpid()));printf(parent pid %d, process group id getpgrp() %d\n, getpid(), getpgrp());sleep(1); //为了观察子进程退出时父进程回收子进程资源}else{perror(fork);exit(1);}return 0;
}子进程成为一个进程组时上面的代码加入如下代码后setpgid(0, 0); //pid 0, pgid 0,让当前进程成为一个进程组并且进程组id为当前进程的pid#include stdio.h
#include unistd.h
#include stdlib.h
#include signal.h
#include sys/types.h
#include sys/wait.hvoid do_sigchld(int signo)
{pid_t pid;int status;printf(signo %d\n, signo);while((pid waitpid(0, status, WNOHANG)) 0) // 0:跟调用进程同组的子进程WNOHANG不阻塞立即返回{if (WIFEXITED(status))printf(child %d exit status %d\n, pid, WEXITSTATUS(status));else if (WIFSIGNALED(status))printf(chid %d exit by signal %d\n, pid, WTERMSIG(status));}
}int main(int argc, char *argv[])
{pid_t pid;//阻塞SIGCHLD信号sigset_t set;sigemptyset(set);sigaddset(set, SIGCHLD);sigprocmask(SIG_BLOCK, set, NULL);pid fork();if (pid 0){//in child//解除阻塞SIGCHLD信号sigprocmask(SIG_UNBLOCK, set, NULL);//进程组printf(child pid %d, process group id getpgid(0) %d\n, getpid(), getpgid(0));printf(child pid %d, process group id getpgid(getpid()) %d\n, getpid(), getpgid(getpid()));printf(child pid %d, process group id getpgrp() %d\n, getpid(), getpgrp());setpgid(0, 0); //pid 0, pgid 0,让当前进程成为一个进程组并且进程组id为当前进程的pidprintf(after setpgid(0, 0) child pid %d, process group id getpgid(0) %d\n, getpid(), getpgid(0));printf(after setpgid(0, 0) child pid %d, process group id getpgid(getpid()) %d\n, getpid(), getpgid(getpid()));printf(after setpgid(0, 0) child pid %d, process group id getpgrp() %d\n, getpid(), getpgrp());}else if (pid 0){//in parent//先捕捉SIGCHLD信号struct sigaction act;act.sa_handler do_sigchld;sigemptyset(act.sa_mask);act.sa_flags 0; //0:用sa_handler参数SA_SIGINFO:用sa_sigaction参数sigaction(SIGCHLD, act, NULL);//再解除阻塞SIGCHLD信号sigprocmask(SIG_UNBLOCK, set, NULL);//进程组printf(parent pid %d, process group id getpgid(0) %d\n, getpid(), getpgid(0));printf(parent pid %d, process group id getpgid(getpid()) %d\n, getpid(), getpgid(getpid()));printf(parent pid %d, process group id getpgrp() %d\n, getpid(), getpgrp());sleep(1); //为了观察子进程退出时父进程回收子进程资源}else{perror(fork);exit(1);}return 0;
}