Linux中有两种异常的进程:
1.孤儿进程:应用通过fork进程后,父进程被kill或者exit,该父进程的子进程被1号进程接管。linux内核启动时候回启动0号进程,启动完毕后0号进程就处于空闲状态,所有的进程的父进程都是有1号进程fork出来的。
2.僵尸进程:fork操作出来的父子进程,子进程收到kil -9的操作或者exit的操作,子进程的内存和CPU资源被操作系统回收,但是PCB块还会在内核中。Linux进程的控制是依靠PCB块的,PCB块记录了进程的运行信息,比如时间片,运行时间,内存资源等等。linux内核按照不同的进程状态把进程放到不同的状态的list中,每次内核会遍历这些list执行对应的进程。
如下就是一个简单的例子,设计到了进程间管道通信、信号注册,信号处理。
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#define TDATA 888
void clear_up(int sig) //收到exit或者kill -9的信号,需要处理的事情
{
while(1)
{
pid_t p = wait(NULL);
if(p == -1) break;
fprintf(stdout,"******recyle %d ok******
",p);
}
}
void exit_fuc()//收到sigint的信号的处理
{
printf("*********exit %d******
",getpid());
exit(0);
}
int main(void) {
int fd[2]; //管道处理,两个进程的通信
signal(SIGCHLD,&clear_up); //信号的注册,改信号是发送退出信号给操作系统时候需要处理的事情
signal(SIGINT,&exit_fuc); //信号注册
pid_t pid = -1;
if(pipe(fd) == -1)
{
return -1;
}
int w_fd = fd[1]; //管道中的fd[1]是写的操作
int r_fd = fd[0];//管道中的fd[0]的是读操作
pid = fork(); //fork一个子进程
assert(pid != -1);
if(pid > 0)
{
close(r_fd);
char buf[4] = {'