day 1进程的创建和回收

进程是程序的一次执行过程,包括BSS段、数据段、代码段、堆和栈等内存结构。进程状态包括运行、等待、停止和死亡态。常用命令如`ps`和`top`用于查看进程信息,`nice`和`renice`调整进程优先级,`fork`用于创建子进程。进程的生命周期涉及父进程与子进程的关系,以及进程的回收和退出机制。
摘要由CSDN通过智能技术生成

进程概念

程序:放在磁盘上的指令和数据的有序集合(文件静态的

进程:执行一个程序所分配的资源的总称,进程是程序的一次执行过程,动态的,包括创建、调度、执行和消亡。

进程和程序的区别

 进程包含的内容

BSS段:存放程序中未初始化的全局变量;

数据段:存放程序中已初始化的全局变量;

代码段:程序执行代码;

堆(heap):堆适用于存放进程运行中被动态分配的内存段(malloc等函数分配内存),当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张), 当利用free等函数释放内存时,被适当的内存从堆中被剔除(堆被缩减);

栈(stack):栈又称为堆栈,使用户存放程序时临时创建的局部变量(但不包括static声明的变量,相当于全局变量,static意味着在数据段中存放变量)局部变量、函数参数、函数返回值

进程控制块(PCB):PID、进程优先级、文件描述符表。

进程类型

交互进程:在shell下启动,以在前台运行,也可以在后台运行。

批处理进程:和在终端无关,被提交到一个作业队列一遍顺序执行。

守护进程:和终端无关,一直在后台运行。

进程状态

运行态:进程正在运行,或者准备运行;

等待态:进程在等待一个事件的发生或某种系统资源;

停止态::进程被中止,收到信号后可继续运行

死亡态(僵尸态 ):已终止的进程,但PCB还没被释放。

进程常用命令

 查看进程信息

ps :查看系统进程快照;

        -e:显示所有信息;

        -l :长格式显示更加详细的信息;

        -f :全部列出,通常和其他选项连用;

        ps -elf|grep test :查看指定进程test;

top:查看进程动态(实时)信息;

        top -p PID 查看指定进程;

        shift + > 后翻页;

        shift + < 前翻页;

/proc:查看进程详细信息;

进程含义:

表头

含义

F

进程标志,说明进程的权限,常见的标志有两个:

  • 1:进程可以被复制,但是不能被执行;
  • 4:进程使用超级用户权限;

S

进程状态。进程状态。常见的状态有以下几种:

  1. -D:不可被唤醒的睡眠状态,通常用于 I/O 情况。
  2. -R:该进程正在运行。
  3. -S:该进程处于睡眠状态,可被唤醒。
  4. -T:停止状态,可能是在后台暂停或进程处于除错状态。
  5. -W:内存交互状态(从 2.6 内核开始无效)。
  6. -X:死掉的进程(应该不会出现)。
  7. -Z:僵尸进程。进程已经中止,但是部分程序还在内存当中。
  8. -<:高优先级(以下状态在 BSD 格式中出现)。
  9. -N:低优先级。
  10. -L:被锁入内存。
  11. -s:包含子进程。
  12. -l :多线程(小写 L)。
  13. -+ :位于后台。

UID

运行此进程的用户的 ID;

PID

进程的 ID;

PPID

父进程的 ID;

C

该进程的 CPU 使用率,单位是百分比;

PRI

进程的优先级,数值越小,该进程的优先级越高,越早被 CPU 执行;

NI

进程的优先级,数值越小,该进程越早被执行;

ADDR

该进程在内存的哪个位置;

SZ

该进程占用多大内存;

WCHAN

该进程是否运行。"-"代表正在运行;

TTY

该进程由哪个终端产生;

TIME

该进程占用 CPU 的运算时间,注意不是系统时间;

CMD

产生此进程的命令名;

进程相关命令

改变程序的优先级

nice :按用户指定的优先级运行进程;

        nice [-n NI值] 命令

        NI范围是-20~19,数值越大优先级越低;

        普通用户只能调整NI值得范围是0~19,而且只能调整自己的进程;

        普通用户只能调高NI值,而不能降低;

        只有root用户才能设定进程NI 值为负值,而且可以调整任何用户的进程。

renice:改变正在运行的进程的优先级;

        renice [优先级] PID

jobs :查看后台进程;

bg :将挂起的进程在后台运行;

fg :把后台运行的进程放到前台运行;

Ctrl + z :把运行的前台进程转为后台并停止;

./test & : 把test程序后台运行

创建子进程

子进程的概念:子进程为由另外一个进程(对应称之为父进程)所创建的进程;

#include <unistd.h>
pid_t fork(void);

创建新的进程,失败时返回-1;

成功时父进程返回子进程的进程号,子进程返回0;

通过fork的返回值区分父进程和子进程。

代码实现:

#include <stdio.h>
#include <unistd.h>
int main(int argc,  char **argv[]) 
{
	pid_t pid;
	pid = fork();
	if (pid > 0) {
		printf("this is father process\n");
	}
	else if(pid == 0) {
		printf("this is child process\n");
	}else if(pid < 0) {
		perror("fork");
        return 0;
	}
	printf("pid=%d\n", (int)pid);
}

执行结果:

 要点:

1、子进程只执行fork之后的代码;

2、父子进程执行顺序是操作系统决定的;

父子进程之间的关系:

1、子进程继承了父进程的内容;

2、父子进程有独立的地址空间,互不影响;

3、若父进程先结束:

        子进程成为孤儿进程,被init进程收养;

        子进程变成后台进程;

4、若子进程先结束:

        父进程如果没有及时回收子进程变成僵尸进程;

子进程进阶

题目1:一个父进程五个子进程;

代码实现:

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

int main()
{
	pid_t pid;
	int i;
	for (i = 0; i < 4; i++) {
		pid = fork();
		if (pid < 0) {
			perror("fork");
			return 0;
		}else if(pid == 0) {
			printf("chaild process\n");
			sleep(1);
            break;
	
		}else{
				printf("father process\n");
				sleep(5);		
		}
	}
	sleep(100);
				
}

题目2:实现一个进程链,父进程->子进程->孙进程->重孙进程->重重孙进程

代码实现:

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

int main()
{
	pid_t pid;
	int i;
	for (i = 0; i < 4; i++) {
		pid = fork();
		if (pid < 0) {
			perror("fork");
			return 0;
		}else if(pid == 0) {
			printf("chaild process\n");
			sleep(1);
	
		}else{
				printf("father process\n");
				sleep(5);
				break;
		}
	}
	sleep(100);
				
}

进程的退出

#include <stdlib.h> 
#include <unistd.h>
void exit(int status);
void _exit(int status);

结束当前的进程并将status返回;

exit结束进程是会刷新缓冲区,_exit不会;

return和exit的区别:

main函数结束时会隐式的调用exit函数,普通函数return是返回上一级;

进程的回收

#include <unistd.h>
pid_t wait(int *status); 

 成功时返回回收的子进程的进程号;失败时返回EOF

 若子进程没有结束,父进程一直阻塞

 若有多个子进程,哪个先结束就先回收

 status 指定保存子进程返回值和结束方式的地址

 status为NULL表示直接释放子进程PCB,不接收返回值

#include <unistd.h>
pid_t waitpid(pid_t pid, int *status, int option);

参数:

pid

pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。

pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。

pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。

pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。

options

options提供了一些额外的选项来控制waitpid,目前在Linux中只支持WNOHANG和WUNTRACED两个选项,这是两个常数,可以用"|"运算符把它们连接起来使用

WNOHANG :若由pid指定的子进程未发生状态改变(没有结束),则waitpid()不阻塞,立即返回0

WUNTRACED: 返回终止子进程信息和因信号停止的子进程信息

wait(wait_stat) 等价于waitpid(-1,wait_stat,0)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值