概念
什么是进程?以及进程和程序的一个区别:
(1)程序是静态的,进程是动态的。程序是有序代码的集合;进程是程序的一次执行。
(2)进程是暂时的,程序是永久的。进程是一个变化的过程,具有独立性和异步性,有生命周期,暂时存在,程序没有生命周期,可长久保存。
(3)进程是操作系统资源分配和保护的基本单位,程序没有此功能。
(4)进程与程序的对应关系。通过多次执行,一个程序可以对应多个进程;通过调用关系,一个进程可以包括多个程序。
(5)进程与程序的结构不同。
程序: 把一个源代码文件经过编译器编译之后,生成一个文件,是可以执行的,这个可执行文件就是程序
text | data bss
代码段 数据段(data:全局或者静态(static)已经初始化的变量。bss: 全局或者静态未始化的变量 )
程序不执行,一直存放在磁盘或者硬盘,静态
进程: 是描述程序的一次执行过程。
程序跟进程不是一一对应,如何区分这些程序,通过pid(进程标识符),唯一的表示一个进程。
操作系统会为每一进程分配资源task_struct(PCB) 和程序运行起来之后所需要的地址空间
pid、state状态、nice优先级
r0-r13、cpsr
进程也是系统资源分配的最小单位,
线程是操作执行的最小单位,并不会为你的线程分配地址空间,线程在进程中创建运行
进程包含三部分: 代码段、数据段、系统数据段
操作系统会为你的进程分配地址空间(分为两部分: 用户空间(0-3G) 和 内核空间(3-4G))
分配的内存空间地址是虚拟地址。
【2】进程类型和状态
1、交互进程:
前台进程:可以输入也可以输出
后台进程:可以输出,但是不可以输入,如果输入数据则会提示错误:
command not found
./while &
2、批处理进程:
gcc编译连接多个.o文件
3、守护进程。
进程状态:
D uninterruptible sleep (usually IO)通常用来实现输入和输出的操作
R running or runnable (on run queue)
正在运行 准备运行
S interruptible sleep (waiting for an event to complete)
睡眠态 (阻塞态) 等待一个时间的完成
T stopped, either by a job control signal or because it is being traced.
暂停态
X dead (should never be seen)
死亡态
Z defunct ("zombie") process, terminated but not reaped by its parent.
僵尸态
实现多个程序同时执行,当子进程结束时,而父进程没有回收子进程所占用的资源,资源会在内存一直保留,那个结束的子进程就处于僵尸状态,如果出现僵尸进程,一定要做处理操作,父进程来做
For BSD formats and when the stat keyword is used, additional characters may be displayed:
< high-priority (not nice to other users)
优先级较高
N low-priority (nice to other users)
优先级较低
s is a session leader会话组的领导者
l is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
进程当中包含有线程
+ is in the foreground process group.
表示的是前台进程组
ps -ajx
kill 发送信号(包括后台进程)
【3】进程的相关系统调用
pid_t fork(void);
功能: 创建新的进程,这个新的进程也称是子进程,子进程是对父进程的精确
拷贝,几乎拷贝了所有内容,但是PID肯定不一样,每个进程拥有一个独立的pid
号。
会把你所有的代码段、数据段中的内容去不拷贝过去
返回值:
成功 pid 在父进程中返回
0 在子进程中返回
失败 -1
僵尸进程:
当子进程结束的时候,父进程并没有对子进程所占的资源进行回收,会一直占用内存,对于这个子进程称作僵尸进程,他所处的状态是僵尸状态。
【注意】避免僵尸进程的出现
孤儿进程:
父进程结束,子进程移交1号进程(init程序),作为子进程的父进程,当子进程结束时,
会有1号进程回收子进程所占用的资源。
pid_t getpid(void);
功能: 在哪个进程中调用了getpid函数。就会返回那个进程pid值
pid_t getppid(void);
功能: 在那个进程中调用了getppid会返回那个进程的父进程的pid值
结束进程 eixt() _exit()
两者都是用来结束进程,但是exit函数结束进程,会事先刷新缓冲区中
的数据, 而_exit不会刷新缓冲区
资源回收的函数:
wait waitpid
功能: 等待子进程状态的改变(三种方式:结束、暂停、恢复)
pid_t wait(int *status);
如果等待不到,会将调用wait函数的进程挂起,也就是阻塞在wait函数这。
wait(&stauts) 《==》 wait(-1, &status, 0)
pid_t waitpid(pid_t pid, int *status, int options);
参数:
-1 meaning wait for any child process.(常用)
等待任意的子进程状态的改变
> 0 meaning wait for the child whose process ID is equal to the value of pid.
1000, 等待pid值等于1000的那个子进程(常用)
< -1 meaning wait for any child process whose process group ID is equal to the absolute value of pid.
-1000 等待进程组1000里面的所有子进程
0 meaning wait for any child process whose process group ID is equal to that of the calling process.
等待以调用进程的pid为gpid的进程组中所有的子进程
options :
0 如果没有子进程状态的改变, 则会阻塞等待
WNOHANG 如果没有等待到子进程退出,则立即返回,继续从waitpid函数下面运行
如果选择了WNOHANG没有等待到子进程状态改变,则会产生僵尸进程,那这个参数没有任何意义,用户需要采用轮训的方式,一只检测子进程状态的改变
while(waitpid(-1, NULL, WNOHANG) == 0);
返回值:
成功 返回状态改变的进程pid值
失败 -1
但是wiatpid如果没有等待到子进程状态改变,会返回0
版权声明:本文为wr132原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。