Linux学习_系统进程结构与分类

进程类型

pstree查看进程树
ps -ef | 想查的运行程序

一、进程链和进程扇

1.概念

  • 进程链:父进程只fork一个子进程,而子进程继续创建子进程,子进程变父进程后不能再创建子进程。简言之:创建进程后,判断父进程退出循环,子进程继续循环
  • 进程扇:与进程链反过来,父进程创建多个子进程,而子进程不再创建子进程。简言之:判断子进程退出循环,父进程继续循环fork

2.创建

  • 进程链创建:
/*
 * 进程链构造.c
 * 进程链构造
 * 
 */


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

int main(int argc, char **argv)
{
	int counter = 0; //记录进程个数
	if(argc<2)counter = 2;
	else counter = atoi(argv[1]);
	
	int i=1; //减掉一个本身启动的进程
	pid_t pid;
	for(; i<counter; ++i){
		pid = fork(); //循环创建进程
		if(pid<0){perror("fork error");exit(1);}
		else if(pid>0)break;
		 //父进程退出循环,子进程继续循环
		}
		printf("pid: %d, ppid: %d\n",getpid(),getppid());
		
		sleep(2);
	return 0;
}


输出

终端输入:
$ ./process_link 4    

pid: 2250, ppid: 2244  //第一个为本身的启动进程,父进程为当前shell 
pid: 2251, ppid: 2250
pid: 2252, ppid: 2251
pid: 2253, ppid: 2252
  • 进程扇创建:
/*
 * 进程扇构造.c
 * 进程扇构造
 * 
 */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
	int counter = 0; //记录进程个数
	if(argc<2)counter = 2;
	else counter = atoi(argv[1]);
	
	int i=1; //减掉一个本身启动的进程
	pid_t pid;
	for(; i<counter; ++i){
		pid = fork(); //循环创建进程,注意不能用vfork()
		if(pid<0){perror("fork error");exit(1);}
		else if(pid==0)break;
		 //子进程退出循环,父进程继续循环
		}
		printf("pid: %d, ppid: %d\n",getpid(),getppid());
		while(1)sleep(1); //持续运行,可以在终端查看进程创建状态
	return 0;
}

输出:

终端查看:
$ ps -ef | grep process_swing

pi        2635  2628  0 10:07 pts/0    00:00:00 ./process_swing 4
pi        2636  2635  0 10:07 pts/0    00:00:00 ./process_swing 4
pi        2637  2635  0 10:07 pts/0    00:00:00 ./process_swing 4
pi        2638  2635  0 10:07 pts/0    00:00:00 ./process_swing 4
pi        2649  2641  0 10:07 pts/2    00:00:00 grep --color=auto process_swing

二、僵尸进程

1.概念:

  • 子进程结束但是没有完全释放内存(在内核中的task_struct(进程表项)没有释放),该进程就成为僵尸进程。
  • 当僵尸进程的父进程结束后就会被init进程领养,最终被回收。
  • 避免僵尸进程:
    • 让僵尸进程的父进程来回收,父进程每隔一段时间来查询子进程是否结束并回收,调用wait()或者waitpid(),通知内核释放僵尸进程。
    • 采用信号SIGCHLD通知处理,并在信号处理程序中调用wait函数。
    • 让僵尸进程成为孤儿进程,由init进程回收。

示例:

/*
 * process_zombie.c
 * zombie, 子进程结束,父进程未结束,子进程内核没有释放
 * 
 */

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

int main(int argc, char **argv)
{
	pid_t pid;
	pid = fork();
	if(pid<0){perror("fork error");exit(1);}
	else if(pid==0){ //child process
		printf("pid: %d,ppid: %d\n", getpid(),getppid());
		exit(0); //子进程结束成为僵尸进程
	}
	while(1)sleep(1); //父进程继续循环
	
	exit(0);

}

输出:

终端:
$ ps -aux | grep process_zombie 

pi        5160  0.0  0.0   1720   312 pts/0    S+   12:53   0:00 ./process_zombie
pi        5161  0.0  0.0      0     0 pts/0    Z+   12:53   0:00 [process_zombie] <defunct>
pi        5179  0.0  0.0   7348   568 pts/2    S+   12:54   0:00 grep --color=auto process_zombie

看到defunct 就是僵尸进程
可以通过kill杀死父进程或者子进程。

$ ./process_zombie &
[1] 5294
$ pid: 5295,ppid: 5294
$ ps -ef | grep process_zombie
pi        5294  5166  0 13:03 pts/2    00:00:00 ./process_zombie
pi        5295  5294  0 13:03 pts/2    00:00:00 [process_zombie] <defunct>
pi        5297  5166  0 13:03 pts/2    00:00:00 grep --color=auto process_zombie
$ kill -9 5295
$ ps -ef | grep process_zombie
pi        5294  5166  0 13:03 pts/2    00:00:00 ./process_zombie
pi        5295  5294  0 13:03 pts/2    00:00:00 [process_zombie] <defunct>
pi        5301  5166  0 13:04 pts/2    00:00:00 grep --color=auto process_zombie
$ kill -9 5294
$ ps -ef | grep process_zombie
pi        5303  5166  0 13:04 pts/2    00:00:00 grep --color=auto process_zombie
[1]+  Killed                  ./process_zombie
$ 


  • exit()说明:
    • 在多个进程时.如果有时要检测上进程是否正常退出的.就要用到上个进程的返回值。
    • exit(0):正常运行程序并退出程序;
    • exit(1):非正常运行导致退出程序;

三、守护进程和孤儿进程

1.守护进程概念

  • 守护进程(daemon守护神)是生存期长的一种进程。他们常常在系统引导装入时启动,在系统关闭时终止。
  • 所有守护进程都以超级用户(用户ID为0)的优先权运行
  • 守护进程没有控制终端。
  • 守护进程的父进程都是init进程。

2.孤儿进程概念

  • 父进程结束,子进程就成为孤儿进程,会由1号进程(init进程)领养

示例:

/*
 * process_orphen.c
 */


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

int main(int argc, char **argv)
{
	pid_t pid;
	pid = fork();
	if(pid<0){perror("fork error");exit(1);}
	else if(pid>0){
		printf("%d deaded\n",getpid());
		exit(0);  //父进程终止
		}
	else {
		sleep(4); //当父进程先终止后,子进程成为孤儿进程
		printf("pid: %d, ppid: %d\n",getpid(),getppid()); //查看当父进程终止后,孤儿进程的父进程变成谁
		}
	return 0;
}


输出:

终端:
$ ./process_orphen

5950 deaded

$ pid: 5951, ppid: 1
被1号进程领养
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值