进程
来源:互联网 发布:淘宝店铺运营方案 编辑:程序博客网 时间:2024/05/17 08:42
传统的程序本身是一组指令的集合,是一个静态实体,无法描述程序在内存中的执行情况,也就不能如实反应程序并发执行过程的特征,为了深刻描述程序动态执行过程的性质,就引入了“进程”的概念。
进程的相关概念
进程在系统中表现为一种数据结构,实现对正在运行的程序过程的抽象,进程有三个部分组成:
- 进程控制块(PCB) ——是描述和控制进程运行的一个数据结构,主要包括进程标识符,进程控制和调度信息等,这些信息使程序成为一个能与其它进程并发运行的进程,操作系统是通过进程控制块来控制进程的运行。
- 代码段——是存放程序代码的数据,假如系统中有多个进程运行相同的一个程序,则可以使用同一个代码段。
- 数据段——存放程序的参数以及程序的局部变量、全局变量、常数以及动态数据分配的数据空间。
- 动态性—— 进程的实质是程序的一次执行过程,进程是动态产生,动态消亡
- 并发性—— 一个进程可以和其它进程一起并发执行
- 独立性—— 进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位
- 异步性—— 由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的,不可预知的速度向前推进
- 就绪状态—— 指进程已分配到处理器以外的所有必要资源,具备了可以执行的所有条件
- 执行状态—— 指进程占用处理器,进程的程序正在执行
- 阻塞状态—— 指进程由于等待某种事件的发生而处于暂停执行的状态
- 交互进程—— 有一个Shell 启动的进程,此类进程有大量的人机交互,既可以在前台运行,也可以在后台运行
- 批处理进程—— 这种进程不需要人机交互,运行于后台,需要大量的系统资源,是一个进程序列
- 监控进程—— 也成为守护进程,Linux启动时启动的进程,并在后台一直运行,等待请求处理任务
在Linux系统中定义了一系列的进程操作函数,包括进程的创建、调度、终止等。
(1)进程的创建
一个进程创建新进程称为创建了子进程,其中创建子进程的进程我们称为父进程,除了创建与被创建之外,父进程与子进程之间的关系也是管理与被管理的关系。
Linux系统启动时处于核心模式,此时只有一个进程:初始化进程(init进程),其进程号为1,linux系统中的所有进程都是由init进程直接或间接创建的。
程序可以通过getpid()获得自身所运行的进程ID(也就是子进程ID),也可以通过getppid()获取父进程的ID,创建进程时,通过函数fork()。
(2)进程的调度
Linux中的进程虽然都是动态分配的,但还是需要考虑最大进程数,在进程中,默认的最大进程数为512,即表示系统中可同时容纳的进程个数为512个。Linux管理进程的最好办法是使用命令来进行管理,主要涉及的命令有ps at top kill pstree nice renice等。
(3)进程的终止
子进程一旦被创建,就与其父进程一起被系统进行调度,子进程运行完毕后,并不立即释放所占有的进程控制表项,而是作为僵进程存在于系统中,直到父进程正常退出或调用wait()函数,子进程才彻底终止。
Pid_t wait(int *status);
Pid_t waitpid(pid_t pid,int *status,int options);
【注意】调用了wait()函数的父进程会马上阻塞自己,由wait()函数自动分析是否当前进程的某一个子进程已经退出,如果找到了这样一个已经变成了僵进程的子进程,wait()函数就会收集这个子进程的信息,将它彻底终止并返回子进程结束状态值;如果没有找到这样的一个子进程,wait()函数就会一直阻塞在这里,直到出现一个变成僵进程的子进程出现为止,但如果父进程还未调用wait()函数就终止了,此时子进程就将被init进程收管,它将控制子进程退出后必须的清除工作。
进程间的通讯
在同一台计算机中的进程相互通信的方式主要有:管道(pipe)、信号(Signal)、信号量(Semaphone)、消息队列(Message)、共享内存(shared memory),其中信号量、消息队列、共享内存被称为IPC机制。
(1)管道
管道是进程直接进行数据交换的通道,管道分为普通管道和命名管道,它们都是通过内核缓冲区按先进先出的方式进行数据传输,普通管道的特点为:
- 半双工
- 只能在具有亲缘关系的进程间使用(如子进程和父进程)
- 单独构成一种独立的文件系统
- 没有名字
- 管道的缓冲区是有限的
- 管道所传送的数据是无格式的
- 写入管道的数据读完之后就从管道中消失
#include<stdio.h>
#include<unistd.h> // 在终端中写程序所要用到的头文件
Int pipe(int fd[2]); //fd[0] 读数据 fd[1] 写数据
一般文件的I/O操作函数都可以用于管道。close(),read(),write()等。
命名管道的创建(包括上边所写的两个头文件)
#include<sys/types.h> //基本系统数据类型的头文件
#include<sys/stat.h> //系统定义文件状态的头文件
int mkfifo(const char *pathname,mode_t mode); //第一个参数:文件名,第二个参数: 文件权限
如果说创建一个FIFO文件,就是说创建一个命名管道文件
(2)信号
信号是一种重要的进程控制方式,类似于中断机制,有某些错误条件而产生的事件,如果不指定,系统就会调用默认操作来处理信号,大部分信号的默认操作将会终止进程。进程可以指定处理函数,由该函数来处理。对于信号的操作,一般的步骤为:安装信号,实现信号处理函数,发送信号。信号的生命周期从信号发送开始,到相应的处理函数执行完毕后结束。
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- 进程
- Code Review 总结一
- JQuery特效多张图片上传
- POJ 1287Networking【prim】
- 关于ARGB_8888、ALPHA_8、ARGB_4444、RGB_565的理解
- POJ 3041 Asteroids
- 进程
- OpenMP中的critical指令
- poj 2318 TOYS 二分+叉积
- 码一波题单+HDOJ题目分类
- Eclipse中集成Tomcat
- 【JVM调优(一)】----JAVA内存模型抽象结构
- 网络namespace引发的疑问(带解答)
- LeetCode | Implement strStr()
- Dubbo 官方 shell 启动脚本(带JVM参数)