进程

来源:互联网 发布:淘宝店铺运营方案 编辑:程序博客网 时间:2024/05/17 08:42

传统的程序本身是一组指令的集合,是一个静态实体,无法描述程序在内存中的执行情况,也就不能如实反应程序并发执行过程的特征,为了深刻描述程序动态执行过程的性质,就引入了“进程”的概念。

进程的相关概念

进程在系统中表现为一种数据结构,实现对正在运行的程序过程的抽象,进程有三个部分组成:

  • 进程控制块(PCB) ——是描述和控制进程运行的一个数据结构,主要包括进程标识符,进程控制和调度信息等,这些信息使程序成为一个能与其它进程并发运行的进程,操作系统是通过进程控制块来控制进程的运行。
  • 代码段——是存放程序代码的数据,假如系统中有多个进程运行相同的一个程序,则可以使用同一个代码段。
  • 数据段——存放程序的参数以及程序的局部变量、全局变量、常数以及动态数据分配的数据空间。
进程的主要特征:

  • 动态性—— 进程的实质是程序的一次执行过程,进程是动态产生,动态消亡
  • 并发性—— 一个进程可以和其它进程一起并发执行
  • 独立性—— 进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位
  • 异步性—— 由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的,不可预知的速度向前推进
由于进程执行时的间断性,运行中的进程可能有三种基本状态:

  • 就绪状态—— 指进程已分配到处理器以外的所有必要资源,具备了可以执行的所有条件
  • 执行状态—— 指进程占用处理器,进程的程序正在执行
  • 阻塞状态—— 指进程由于等待某种事件的发生而处于暂停执行的状态
三种进程:

  • 交互进程—— 有一个Shell 启动的进程,此类进程有大量的人机交互,既可以在前台运行,也可以在后台运行
  • 批处理进程—— 这种进程不需要人机交互,运行于后台,需要大量的系统资源,是一个进程序列
  • 监控进程—— 也成为守护进程,Linux启动时启动的进程,并在后台一直运行,等待请求处理任务
进程的操作

在Linux系统中定义了一系列的进程操作函数,包括进程的创建、调度、终止等。

        (1)进程的创建

一个进程创建新进程称为创建了子进程,其中创建子进程的进程我们称为父进程,除了创建与被创建之外,父进程与子进程之间的关系也是管理与被管理的关系。

Linux系统启动时处于核心模式,此时只有一个进程:初始化进程(init进程),其进程号为1linux系统中的所有进程都是由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)信号

信号是一种重要的进程控制方式,类似于中断机制,有某些错误条件而产生的事件,如果不指定,系统就会调用默认操作来处理信号,大部分信号的默认操作将会终止进程。进程可以指定处理函数,由该函数来处理。对于信号的操作,一般的步骤为:安装信号,实现信号处理函数,发送信号。信号的生命周期从信号发送开始,到相应的处理函数执行完毕后结束。

0 0