• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2019-11-08 05:26 Aet 隐藏边栏 |   抢沙发  7 
文章评分 1 次,平均分 5.0

进程介绍

Process

  • 计算机中的程序关于某数据集合上的一次运行活动。
  • 它是操作系统进行资源分配和调度的基本单位。

进程的内容

  • 逻辑内存
  • 文件/网络句柄
    • 所有进程共有的。
  • 线程

进程的特征

  • 动态性
    进程是程序的执行,同时进程有生命周期。
  • 并发性
    多个进程可同存在与内存中,能在一段时间内同时执行。
  • 独立性
    资源分配和调度的基本单位。
  • 制约性
    • 并发进程间存在制约关系,造成程序速度不可预期性,必须对进程的并发执行次序、相对执行速度加以协调。

进程的状态

  • 运行态
    当进程得到处理机,并且进程的执行程序在处理机上运行时的状态成为运行状态。
  • 就绪态
    当一个进程已经准备就绪,一旦得到CPU,就可立即运行,这时进程所处的状态成为就绪状态。
    系统中有一个就绪进程队列,处于就绪状态的进程按照某种调度策略存在于该队列中。
  • 等待态(阻塞态)
    若一个进程正等待某一件事发生(比如等待输入或输出操作的完成什么的)而暂时停止执行的状态称为等待状态。
    处于等待状态的进程,不具备运行的条件,即使给它CPU,也无法执行。
    系统中有几个等待进程队列,这个队列时按照所等待的事件组成的相应的等待队列。

进程间通信的方式

管道-无名管道

  • 它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。
  • 它只能用于具有亲缘关系的进程之间的通信(即父子进程之间、兄弟进程之间)。
  • 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read,write等函数。但它不是普通的文件,并不属于其他任何文件系统,并且只用于内存中。
    原型:

    示例:
    数据流从父进程流向子进程,关闭父进程读端(fd[0])与子进程写端(fd[1]);反之亦然。

管道-有名管道

  • FIFO,是一种文件类型
  • FIFO可以在无关的进程之间交换数据,区别与无名管道。
  • FIFO有路径名与之相关联,它以一种特殊设备文件形式存在与文件系统中。
    原型:

  • 一旦创建了一个FIFO,就可以用一般的I/O函数操作它
  • 当open一个FIFO时,如果设置了非阻塞标志(0_NONBLOCK),则只读open立即返回。而只写open将出错返回-1,如果没有进程为了读而打开该FIFO,其errno置ENXIO。
  • 如果没有设置非阻塞标志,只读open要阻塞到某个其他进程为写而打开此FIFO。类似,只写open要阻塞到某个其他进程为读而打开它。
    示例:
    write_fifo.c

    read_fifo.c

消息队列

消息队列,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识。
特点:

  • 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。
  • 消息队列独立于发送或接收进程。进程终止时,消息队列及其内容并不会被删除。
  • 消息队列可以实现消息的随机查询,消息不一定要先进先出的次序读取,也可以按消息的类型读取。
    原型:

    什么时候msgget将创建一个新的消息队列?

  • 如果没有与键值key相对于的消息队列,并且flag中包含了IPC_CREATE标志位
  • key参数为IPC_PRIVATE
    msgrcv在读取消息队列时,type参数有以下情况:
  • type == 0,返回消息队列中的第一个消息
  • type > 0,返回队列中消息类型为type的第一个消息
  • type < 0,返回队列中消息类型值小于或等于type绝对值的消息。如果这样的消息有多个,则取类型值最小的消息。
    msg_server.c

    msg_client.c

信号量

信号量是一个计数器,用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。
特点:

  • 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存。
  • 信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作。
  • 每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数。
  • 支持信号量组。
    原型:
    最简单的信号量是只能取 0 和 1 的变量,这也是信号量最常见的一种形式,叫做二值信号量。
    而可以取多个正整数的信号量被称为通用信号量。

    semget创建新的信号量集合时,必须指定集合中信号量的个数(即num_sems),通常为1; 如果是引用一个现有的集合,则将num_sems指定为 0 。

  • sem_op > 0,表示进程释放相应的资源数,将 sem_op 的值加到信号量的值上。如果有进程正在休眠等待此信号量,则唤醒它们。
  • sem_op < 0,请求 sem_op 的绝对值的资源。如果相应的资源数可以满足请求,则将该信号量的值减去sem_op的绝对值,函数成功返回;当相应的资源数不能满足请求时,这个操作与sem_flg有关。如sem_flg 指定IPC_NOWAIT,则semop函数出错返回EAGAIN。sem_flg 没有指定IPC_NOWAIT,则将该信号量的semncnt值加1,然后进程挂起直到下述情况发生:
    1-当相应的资源数可以满足请求,此信号量的semncnt值减1,该信号量的值减去sem_op的绝对值。成功返回;
    2-此信号量被删除,函数smeop出错返回EIDRM;
    3-进程捕捉到信号,并从信号处理函数返回,此情况下将此信号量的semncnt值减1,函数semop出错返回EINTR
  • sem_op == 0,进程阻塞直到信号量的相应值为0:
    当信号量已经为0,函数立即返回。如果信号量的值不为0,则依据sem_flg决定函数动作:
    sem_flg指定IPC_NOWAIT,则出错返回EAGAIN;sem_flg没有指定IPC_NOWAIT,则将该信号量的semncnt值加1,然后进程挂起直到下述情况发生:
    1-信号量值为0,将信号量的semzcnt的值减1,函数semop成功返回;
    2-此信号量被删除,函数smeop出错返回EIDRM;
    3-进程捕捉到信号,并从信号处理函数返回,在此情况将此信号量的semncnt值减1,函数semop出错返回EINTR
    semctl函数中的命令有多种,这里就说两个常用的:
  • SETVAL:用于初始化信号量为一个已知的值。所需要的值作为联合semun的val成员来传递。在信号量第一次使用之前需要设置信号量。
  • IPC_RMID:删除一个信号量集合。如果不删除信号量,它将继续在系统中存在,即使程序已经退出,它可能在你下次运行此程序时引发问题,而且信号量是一种有限的资源。
    示例:

共享内存

指两个或多个进程共享一个给定的存储区
特点:

  • 共享内存是最快的一种IPC,因为进程是直接对内存进行存取的。
  • 因为多个进程可以同时操作,所以需要进程同步。
  • 信号量和共享内存通常结合在一起使用,信号量用来同步对共享内存的访问。
    原型:
  • 当用shmget创建一段共享内存时,必须指定size;而如果引用一个已存在的共享内存,则将size指定为0。
  • 当一段共享内存被创建以后,它不能被任何进程访问。必须使用shmat函数连接该共享内存到当前进程的地址空间,连接成功后把共享内存区对象映射到调用进程的地址空间,随后便可像本地空间一样访问。
  • shmdt函数是用来断开shmat建立的连接的。需要注意的是,这并不是从系统中删除该共享内存,只是当前进程不能再房屋内该共享内存而已。
  • shmctl函数可以对共享内存执行多种操作,根据cmd参数执行相对的操作,常用的是IPC_RMID(从系统中删除该共享内存)
    示例:
    server.c

    client.c

    Socket(支持不同主机上的两个进程通信)

    Streams(支持不同主机上的两个进程通信)

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2021-11-21
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享