精华内容
下载资源
问答
  • 2021-06-02 22:15:05

    进程的阻塞是指使一个进程让出处理器,去等待一个事件,如等待资源、等待I/O完成、等待一个事件发等,通常进程自己调用阻塞原语阻塞自己,所以,是进程自主行为,是1个同步事件。当一个等待事件结束会产生一个中断,从而,激活操作系统,在系统的控制之下将被阻塞的进程唤醒,如I/O操作结束、某个资源可用或期待事件出现。进程的阻塞和唤醒显然是由进程切换来完成。

    更多相关内容
  • 主要介绍了php多进程中的阻塞与非阻塞操作,结合实例形式分析了php多进程中的阻塞与非阻塞原理、阻塞控制方法与相关操作技巧,需要的朋友可以参考下
  • 主要介绍了php 多进程编程父进程阻塞与非阻塞,结合实例形式分析了php 多进程编程中父进程阻塞、等待、子进程退出、非阻塞等相关操作技巧,需要的朋友可以参考下
  • 本文主要介绍了 Linux中进程阻塞和挂起的区别。
  • 前一阵子在研究文档展示时使用了java进程直接调用外部程序,其中遇到一个问题花了好长时间才解决,这个问题就是外部程序直接执行没什么问题,但是当使用Java进程执行时外部程序就阻塞在那儿不动了。而且这个外部程序在...
  • linux进程 阻塞和非阻塞操作

    千次阅读 2021-05-10 03:47:24
    有时实现正确的 unix 语义要求一个操作不阻塞, 即便它不能完全地进行下去.有时还有调用进程通知你他不想阻塞, 不管它的 I/O 是否继续. 明确的非阻塞 I/O 由 filp->f_flags 中的 O_NONBLOCK 标志来指示. 这个标志...

    在我们看全功能的 read 和 write 方法的实现之前, 我们触及的最后一点是决定何时使 进程睡眠. 有时实现正确的 unix 语义要求一个操作不阻塞, 即便它不能完全地进行下去.

    有时还有调用进程通知你他不想阻塞, 不管它的 I/O 是否继续. 明确的非阻塞 I/O 由 filp->f_flags 中的 O_NONBLOCK 标志来指示. 这个标志定义于 , 被

    自动包含. 这个标志得名自"打开-非阻塞", 因为它可在打开时指定(并且起

    初只能在那里指定). 如果你浏览源码, 你会发现一些对一个 O_NDELAY 标志的引用; 这 是一个替代 O_NONBLOCK 的名子, 为兼容 System V 代码而被接受的. 这个标志缺省地被 清除, 因为一个等待数据的进程的正常行为仅仅是睡眠. 在一个阻塞操作的情况下, 这是 缺省地, 下列的行为应当实现来符合标准语法:

    · 如果一个进程调用 read 但是没有数据可用(尚未), 这个进程必须阻塞. 这个进程 在有数据达到时被立刻唤醒, 并且那个数据被返回给调用者, 即便小于在给方法的 count 参数中请求的数量.

    · 如果一个进程调用 write 并且在缓冲中没有空间, 这个进程必须阻塞, 并且它必 须在一个与用作 read 的不同的等待队列中. 当一些数据被写入硬件设备, 并且在

    输出缓冲中的空间变空闲, 这个进程被唤醒并且写调用成功, 尽管数据可能只被部 分写入如果在缓冲只没有空间给被请求的 count 字节.

    这 2 句都假定有输入和输出缓冲; 实际上, 几乎每个设备驱动都有. 要求有输入缓冲是 为了避免丢失到达的数据, 当无人在读时. 相反, 数据在写时不能丢失, 因为如果系统调

    用不能接收数据字节, 它们保留在用户空间缓冲. 即便如此,

    输出缓冲几乎一直有用, 对 于从硬件挤出更多的性能.

    在驱动中实现输出缓冲所获得的性能来自减少了上下文切换和用户级/内核级切换的次数. 没有一个输出缓冲(假定一个慢速设备), 每次系统调用接收这样一个或几个字符, 并且当 一个进程在 write 中睡眠, 另一个进程运行(那是一次上下文切换). 当第一个进程被唤 醒, 它恢复(另一次上下文切换), 写返回(内核/用户转换), 并且这个进程重新发出系统 调用来写入更多的数据(用户/内核转换); 这个调用阻塞并且循环继续.

    增加一个输出缓 冲可允许驱动在每个写调用中接收大的数据块, 性能上有相应的提高. 如果这个缓冲足够 大, 写调用在第一次尝试就成功 -- 被缓冲的数据之后将被推到设备 -- 不必控制需要返 回用户空间来第二次或者第三次写调用. 选择一个合适的值给输出缓冲显然是设备特定的.

    我们不使用一个输入缓冲在 scull 中, 因为数据当发出 read 时已经可用.

    类似的, 不用 输出缓冲, 因为数据被简单地拷贝到和设备关联的内存区. 本质上, 这个设备是一个缓冲, 因此额外缓冲的实现可能是多余的. 我们将在第 10 章见到缓冲的使用.

    如果指定

    O_NONBLOCK, read 和 write 的行为是不同的. 在这个情况下, 这个调用简单 地返回 -EAGAIN(("try it

    agin")如果一个进程当没有数据可用时调用 read , 或者如果 当缓冲中没有空间时它调用 write .

    如你可能期望的,

    非阻塞操作立刻返回, 允许这个应用程序轮询数据. 应用程序当使用 stdio 函数处理非阻塞文件中, 必须小心, 因为它们容易搞错一个的非阻塞返回为 EOF.

    它们始终必须检查 errno.

    自然地, O_NONBLOCK 也在 open 方法中有意义. 这个发生在当这个调用真正阻塞长时间 时; 例如, 当打开(为读存取)一个 没有写者的(尚无)FIFO, 或者存取一个磁盘文件使用

    一个悬挂锁. 常常地, 打开一个设备或者成功或者失败, 没有必要等待外部的事件. 有时, 但是, 打开这个设备需要一个长的初始化, 并且你可能选择在你的 open 方法中支持 O_NONBLOCK , 通过立刻返回 -EAGAIN,如果这个标志被设置. 在开始这个设备的初始化进 程之后. 这个驱动可能还实现一个阻塞 open 来支持存取策略, 通过类似于文件锁的方式. 我们将见到这样一个实现在"阻塞 open 作为对

    EBUSY 的替代"一节, 在本章后面.

    一些驱动可能还实现特别的语义给 O_NONBLOCK;

    例如, 一个磁带设备的 open 常常阻塞 直到插入一个磁带. 如果这个磁带驱动器使用 O_NONBLOCK 打开, 这个 open 立刻成功, 不管是否介质在或不在.

    只有 read, write, 和

    open 文件操作受到非阻塞标志影响.

    简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型

    1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...

    Linux设备驱动中的阻塞和非阻塞I/O

    [基本概念] 1.阻塞 阻塞操作是指在执行设备操作时,托不能获得资源,则挂起进程直到满足操作所需的条件后再进行操作.被挂起的进程进入休眠状态(不占用cpu资源),从调度器的运行队列转移到等待队列,直到 ...

    蜕变成蝶~Linux设备驱动中的阻塞和非阻塞I/O

    今天意外收到一个消息,真是惊呆我了,博客轩给我发了信息,说是俺的博客文章有特色可以出本书,,这简直让我受宠若惊,俺只是个大三的技术宅,写的博客也是自己所学的一些见解和在网上看到我一些博文以及帖子里综合 ...

    linux驱动编写之阻塞与非阻塞

    一.概念 应用程序使用API接口,如open.read等来最终操作驱动,有两种结果--成功和失败.成功,很好处理,直接返回想要的结果:但是,失败,是继续等待,还是返回失败类型呢?  如果继续等待,将进 ...

    python全栈开发day31-操作系统介绍,异步、同步、阻塞、非阻塞,进程

    一.网络编程内容回顾 1.arp协议 #交换机 #广播.单播 2.ip协议 3.tcp和udp协议 tcp:可靠的,面向连接的,字节流传输,长连接 三次握手:一方发送请求,另一方确认请求同时发送请求, ...

    Linux设备驱动中的IO模型---阻塞和非阻塞IO【转】

    在前面学习网络编程时,曾经学过I/O模型 Linux 系统应用编程——网络编程(I/O模型),下面学习一下I/O模型在设备驱动中的应用. 回顾一下在Unix/Linux下共有五种I/O模型,分别是: ...

    《linux设备驱动开发详解》笔记——8阻塞与非阻塞IO

    8.1 阻塞与非阻塞IO 8.1.0 概述 阻塞:访问设备时,若不能获取资源,则进程挂起,进入睡眠状态:也就是进入等待队列 非阻塞:不能获取资源时,不睡眠,要么退出.要么一直查询:直接退出且无资源时, ...

    Linux中同步与异步、阻塞与非阻塞概念以及五种IO模型

    1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...

    从linux源码看socket的阻塞和非阻塞

    从linux源码看socket的阻塞和非阻塞 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情. 大部分高性能网络框架采用的是非阻塞模式.笔者这次就从linux ...

    Linux设备驱动中的阻塞和非阻塞I/O <转载>

    Green 博客园 首页 新随笔 联系 订阅 管理 Linux设备驱动中的阻塞和非阻塞I/O   [基本概念] 1.阻塞 阻塞操作是指在执行设备操作时,托不能获得资源,则挂起进程直到满足操作所需的条件 ...

    随机推荐

    Java中的Bigdecimal类型运算

    Java中的Bigdecimal类型运算 双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更小的数进行运算和处理.Java在java.math包中提 供的API类BigD ...

    ASP.NET MVC- EF返回连接池用ADO.NET方式访问数据库

    用习惯了ADO.NET的方式去访问数据库,虽然ADO.NET写的代码没有EF简洁,可是也并不麻烦.而且EF在进行多表查询的那种方式是,EF需要先去数据库里定义外键,再进去一次代码生成,然后才能用INC ...

    jQuery自学笔记(二):jQuery选择器

    一.简单选择器 ID选择器:$('#box') 元素标签名:$('div') 类选择器:$('.box') jQuery提供了length和size()两种方法查看返回的元素,可验证ID在页面只出现一 ...

    真实经纬度(gps)转成百度坐标的js方法

    转:http://www.360doc.com/content/16/0320/14/18636294_543805051.shtml 结果图:

    【Demo 0009】Android 组件(BroadcastReceiver)

    本章学习要点:        1.  了解Broadcast的作用;        2.  掌握自定义广播和系统广播的接收:        3.  掌握广播的发送:

    SpringCloud学习笔记(4)——Zuul

    参考Spring Cloud官方文档第19章 19. Router and Filter: Zuul 路由是微服务架构的一部分.例如,"/"可能映射到你的web应用,"/ ...

    [Swift]LeetCode898. 子数组按位或操作 | Bitwise ORs of Subarrays

    We have an array A of non-negative integers. For every (contiguous) subarray B = [A[i], A[i+1], ..., ...

    Centos7安装Nginx+PHP+MySQL

    之前曾经在服务器上从头到尾搭过一次环境,但那时新手一枚,很多地方搞不定,是前辈帮忙解决的.这次独自一人在服务器上撘环境,感慨上次没有做好相关笔记,所以事后整理一下,下次再搭环境时可以轻车熟路. 一.准 ...

    hibernate---级联保存、级联删除

    直接上菜: dept.hbm.xml:关键点标蓝色这部分,inverse表示放弃维护外键关系,cascade就不用说了

    展开全文
  • 下面小编就为大家带来篇python 简单搭建阻塞式单进程,多进程,多线程服务的实例。小编觉得挺不错的,现在就分享给大家,也给大家做参考。一起跟随小编过来看看吧
  • python 进程(process)阻塞

    千次阅读 2020-12-10 14:58:08
    背景:来观察测试一下python进程(process)的阻塞、普通进程和守护进程又有什么区别、进程池又是什么、进程池怎么异步提交任务等等、公共代码首先先贴上一些公共代码,下面的例子都基于这份公共代码运行(注:替换...

    背景:来观察测试一下python 进程(process)的阻塞、普通进程和守护进程又有什么区别、进程池又是什么、进程池怎么异步提交任务等等

    一、公共代码

    首先先贴上一些公共代码,下面的例子都基于这份公共代码运行(注:替换xxx的内容)

    importtimeimportmultiprocessingdefworker(name):print('%s: %s start...' % (time.strftime('%X'), name))

    time.sleep(2)print('%s: %s done.' % (time.strftime('%X'), name))defxxx():pass

    if __name__ == '__main__':

    xxx()

    二、单进程阻塞

    def单进程阻塞():

    t= multiprocessing.Process(target=worker, args=('张三',))

    t.start()#阻塞

    t.join()print('Finished')

    运行结果:

    解释:阻塞进程的情况下,程序会先等待进程任务执行完,再往下执行其他代码

    三、单进程不阻塞

    def单进程不阻塞():

    t= multiprocessing.Process(target=worker, args=('李四',))

    t.start()print('Finished')

    运行结果:

    解释:不阻塞进程的情况下,程序会直接往下走,进程任务是后完成的(因为我在进程任务里加了 sleep),类似于异步;同时,我们还可以发现,程序执行完最后一行代码之后,如果进程任务还没完成,程序是不会马上死掉的,还是会等进程任务执行完才会结束程序。

    四、多进程的错误阻塞

    def多进程的错误阻塞():

    t1= multiprocessing.Process(target=worker, args=('张三',))

    t1.start()

    t1.join()

    t2= multiprocessing.Process(target=worker, args=('李四',))

    t2.start()

    t2.join()print('Finished')

    运行结果:

    解释:t1.join 直接阻塞了程序,t2还没start,t1.join阻塞程序直到t1的任务已完成。所以会看到 张三 done 之后,李四 才能 start

    五、多进程的正确阻塞

    def多进程的正确阻塞():

    t1= multiprocessing.Process(target=worker, args=('张三',))

    t2= multiprocessing.Process(target=worker, args=('李四',))

    t1.start()

    t2.start()

    t1.join()

    t2.join()print('Finished')

    运行结果:

    解释:需要将所有进程都start之后,才能阻塞(join);进程任务也不是按顺序执行和完成了,哪个先完成,得看哪个进程任务耗时少,也有可能会同时完成(并发)

    按下面代码,修改一下worker函数,给李四加一下速,再执行一次看看:

    defworker(name):print('%s: %s start...' % (time.strftime('%X'), name))

    time.sleep(2 if name == '张三' else 1)print('%s: %s done.' % (time.strftime('%X'), name))

    注:多执行几次,你会发现,明明是t1.start() 再 t2.start(),为何回显总是 李四 start 在前。那是因为阻塞的进程,执行过程中是不会回显的,它需要执行完毕后才会一起回显。因为总是 李四 done 先,所以回显示就总是 李四 start 在前

    温馨提示:测试完记得把 worker 函数改回原来的样子,下面例子是以原版的 worker 为基础的

    六、多进程不阻塞

    def多进程不阻塞():

    t1= multiprocessing.Process(target=worker, args=('张三',))

    t2= multiprocessing.Process(target=worker, args=('李四',))

    t1.start()

    t2.start()print('Finished')

    运行结果:

    解释: 参考上面单进程不阻塞↑,不阻塞的情况下,也是会等待全部进程任务执行完成才结束程序的。多进程有一定的并发现象

    七、守护进程阻塞

    def守护进程阻塞():

    t1= multiprocessing.Process(daemon=True, target=worker, args=('张三',))

    t2= multiprocessing.Process(daemon=True, target=worker, args=('李四',))

    t1.start()

    t2.start()

    t1.join()

    t2.join()print('Finished')

    运行结果:

    解释:这里看着上面的普通进程没有什么区别的,具体的区别看下面↓↓↓

    八、守护进程不阻塞

    def守护进程不阻塞():

    t1= multiprocessing.Process(daemon=True, target=worker, args=('张三',))

    t2= multiprocessing.Process(daemon=True, target=worker, args=('李四',))

    t1.start()

    t2.start()print('Finished')

    运行结果:

    解释:进程任务都还没执行,主程序就执行完毕,结束了。这是守护进程(后台进程)的一个特点:不阻塞的情况下,后台进程(守护进程)会在主程序结束的时候自动死掉

    九、守护进程不阻塞但主进程比较晚结束

    def守护进程不阻塞但主进程比较晚结束():

    t1= multiprocessing.Process(daemon=True, target=worker, args=('张三',))

    t2= multiprocessing.Process(daemon=True, target=worker, args=('李四',))

    t1.start()

    t2.start()

    time.sleep(5)print('Finished')

    运行结果:

    解释:这里的主进程并没有等子(守护)进程,只是主进程耗时比子进程还要久,子进程先执行完毕了

    十、进程池阻塞

    def进程池阻塞():

    with multiprocessing.Pool(processes=3) as pp:

    pp.apply(worker, ('张三',))

    pp.apply(worker, ('李四',))

    pp.close()

    pp.join()print('Finished')

    运行结果:

    解释:运行结果基本和“多进程的正确阻塞”基本一样,但又有一点不同,详情请看下面 “十二” 点~

    十一、进程池不阻塞

    def进程池不阻塞():

    with multiprocessing.Pool(processes=3) as pp:

    pp.apply(worker, ('张三',))

    pp.apply(worker, ('李四',))

    pp.close()print('Finished')

    运行结果:

    解释:这不阻塞的效果感觉和阻塞的效果并没有什么区别

    十二、进程池的奇怪现象

    认真观察一下“十、进程池阻塞”和“十一、进程池不阻塞”,还有一个现象,不管是阻塞还是不阻塞,就上面的例子而言,李四居然要等张三done之后才能start,它们不应该同时start,同时done的吗??

    对比一下上面“五、多进程的正确阻塞”的运行结果 和 “十一、进程池不阻塞”的结果:

    解释:普通的多进程 start 是一起的(并发,单任务不阻塞),done的话就看任务的实际耗时。进程池的话,使用apply添加任务的时候,会自动阻塞任务,一个任务完成,再才执行下一个apply的任务。只想阻塞进程池,不要阻塞单任务的话,可以使用 apply_async 方法,详情请看下面↓↓↓

    十三、进程池异步阻塞

    def进程池异步阻塞():

    with multiprocessing.Pool(processes=3) as pp:

    pp.apply_async(worker, ('张三',))

    pp.apply_async(worker, ('李四',))

    pp.close()

    pp.join()print('Finished')

    运行结果:

    解释,这下就真的和“多进程的正确阻塞”一样的,不会阻塞单任务

    十四、进程池异步不阻塞

    def进程池异步不阻塞():

    with multiprocessing.Pool(processes=3) as pp:

    pp.apply_async(worker, ('张三',))

    pp.apply_async(worker, ('李四',))

    pp.close()print('Finished')

    运行结果:

    解释:异步不阻塞的话,就会和守护进程一样,主程序不会等待进程任务完成,会直接结束程序

    十五、进程池同步并发不阻塞

    上面说的apply是同步提交任务,apply_async是异步提交任务。apply是会阻塞的,顺序执行任务。那有没有同步又并发的方法呢?答案是有的,可以用map方法:

    def进程池同步并发不阻塞():

    with multiprocessing.Pool(processes=3) as pp:

    pp.map(worker, ['张三', '李四'])

    pp.close()print('Finished')

    运行结果:

    解释:提供给map方法一个函数和参数列表,它会迭代参数列表,并发执行函数~

    需要注意的是,map和apply一样,是同步且阻塞的,多次调用map方法会和多次调用apply一样,会阻塞,需要等待第一次map任务执行完毕才会执行下面的map

    def进程池同步并发阻塞():

    with multiprocessing.Pool(processes=3) as pp:

    pp.map(worker, ['张三', '李四'])

    pp.map(worker, ['王五', '赵六'])

    pp.close()print('Finished')

    运行结果:

    完。

    展开全文
  • 操作系统课程设计(作业调度、内存管理、进程调度、进程阻塞等),含完整源代码和课程设计报告,内容优质
  • 模拟进程创建、终止、阻塞、唤醒原语--附带注释.pdf
  • 采用UDP方式的进程间通信模型,支持非阻塞,socket编程,采用select网络模型。 采用UDP方式的进程间通信模型,支持非阻塞,socket编程,采用select网络模型。 采用UDP方式的进程间通信模型,支持非阻塞,socket编程...
  • 文章目录进程如何阻塞?进程阻塞为什么不消耗CPU?1. 计算机是如何接收数据的2. 计算机如何知道要接受数据?3. 进程阻塞为什么不占用 CPU 资源?3.1 工作队列3.2 等待队列3.3 唤醒进程...下边是一个典型的计算机结构图

    进程如何阻塞?进程阻塞为什么不消耗CPU?

    要想明白进程如何阻塞,阻塞为什么不消耗CPU,就要先明白

    • 计算机是如何接受数据的
    • 计算机如何知道什么时候要接收数据

    1. 计算机是如何接收数据的

    从网卡接收数据说起:

    下边是一个典型的计算机结构图,计算机由 CPU、存储器(内存)与网络接口等部件组成,先从硬件的角度看计算机怎样接收网络数据。

    在这里插入图片描述
    下图展示了网卡接收数据的过程:

    • 在 1 阶段,网卡收到网线传来的数据。
    • 经过 2 阶段的硬件电路的传输。
    • 最终 3 阶段将数据写入到内存中的某个地址上。

    这个过程涉及到 DMA 传输、IO 通路选择等硬件有关的知识,但我们只需知道:网卡会把接收到的数据写入内存。

    在这里插入图片描述
    网卡接收数据的过程:
    通过硬件传输,网卡接收的数据存放到内存中,操作系统就可以去读取它们。

    2. 计算机如何知道要接受数据?

    答:中断

    • 计算机执行程序时,会有优先级的需求。比如,当计算机收到断电信号时,它应立即去保存数据,保存数据的程序具有较高的优先级(电容可以保存少许电量,供 CPU 运行很短的一小段时间)。
    • 一般而言,由硬件产生的信号需要 CPU 立马做出回应,不然数据可能就丢失了,所以它的优先级很高。
    • CPU 理应中断掉正在执行的程序,去做出响应;当 CPU 完成对硬件的响应后,再重新执行用户程序。

    中断的过程如下图,它和函数调用差不多,只不过函数调用是事先定好位置,而中断的位置由“信号”决定。

    在这里插入图片描述

    中断程序调用

    以键盘为例,当用户按下键盘某个按键时,键盘会给 CPU 的中断引脚发出一个高电平,CPU 能够捕获这个信号,然后执行键盘中断程序。

    下图展示了各种硬件通过中断与 CPU 交互的过程:
    在这里插入图片描述
    现在可以回答“如何知道接收了数据?”这个问题了:当网卡把数据写入到内存后,网卡向 CPU 发出一个中断信号,操作系统便能得知有新数据到来,再通过网卡中断程序去处理数据。

    3. 进程阻塞为什么不占用 CPU 资源?

    从操作系统进程调度的角度来看数据接收。阻塞是进程调度的关键一环,指的是进程在等待某事件(如接收到网络数据)发生之前的等待状态,Recv、Select 和 Epoll 都是阻塞方法。

    下边分析一下进程阻塞为什么不占用 CPU 资源?为简单起见,我们从普通的 Recv 接收开始分析,先看看下面代码:

    //创建socket 
    int s = socket(AF_INET, SOCK_STREAM, 0);    
    //绑定 
    bind(s, ...) 
    //监听 
    listen(s, ...) 
    //接受客户端连接 
    int c = accept(s, ...) 
    //接收客户端数据 
    recv(c, ...); 
    //将数据打印出来 
    printf(...) 
    

    这是一段最基础的网络编程代码,先新建 Socket 对象,依次调用 Bind、Listen 与 Accept,最后调用 Recv 接收数据。

    Recv 是个阻塞方法,当程序运行到 Recv 时,它会一直等待,直到接收到数据才往下执行。那么阻塞的原理是什么?

    3.1 工作队列

    操作系统为了支持多任务,实现了进程调度的功能,会把进程分为“运行”和“等待”等几种状态。

    运行状态是进程获得 CPU 使用权,正在执行代码的状态;等待状态是阻塞状态,比如上述程序运行到 Recv 时,程序会从运行状态变为等待状态,接收到数据后又变回运行状态。

    操作系统会分时执行各个运行状态的进程,由于速度很快,看上去就像是同时执行多个任务。

    下图的计算机中运行着 A、B 与 C 三个进程,其中进程 A 执行着上述基础网络程序,一开始,这 3 个进程都被操作系统的工作队列所引用,处于运行状态,会分时执行。

    在这里插入图片描述
    工作队列中有 A、B 和 C 三个进程

    3.2 等待队列

    当进程 A 执行到创建 Socket 的语句时,操作系统会创建一个由文件系统管理的 Socket 对象(如下图)。

    在这里插入图片描述

    创建 Socket

    这个 Socket 对象包含了发送缓冲区、接收缓冲区与等待队列等成员。等待队列是个非常重要的结构,它指向所有需要等待该 Socket 事件的进程。

    当程序执行到 Recv 时,操作系统会将进程 A 从工作队列移动到该 Socket 的等待队列中(如下图)。

    在这里插入图片描述
    Socket 的等待队列

    由于工作队列只剩下了进程 B 和 C,依据进程调度,CPU 会轮流执行这两个进程的程序,不会执行进程 A 的程序。所以进程 A 被阻塞,不会往下执行代码,也不会占用 CPU 资源。

    注:操作系统添加等待队列只是添加了对这个“等待中”进程的引用,以便在接收到数据时获取进程对象、将其唤醒,而非直接将进程管理纳入自己之下。上图为了方便说明,直接将进程挂到等待队列之下。

    3.3 唤醒进程

    当 Socket 接收到数据后,操作系统将该 Socket 等待队列上的进程重新放回到工作队列,该进程变成运行状态,继续执行代码。

    同时由于 Socket 的接收缓冲区已经有了数据,Recv 可以返回接收到的数据。

    3.4 内核接收网络数据全过程

    这一步,贯穿网卡、中断与进程调度的知识,叙述阻塞 Recv 下,内核接收数据的全过程。
    在这里插入图片描述
    内核接收数据全过程

    如上图所示,进程在 Recv 阻塞期间:

    • 计算机收到了对端传送的数据(步骤 ①)
    • 数据经由网卡传送到内存(步骤 ②)
    • 然后网卡通过中断信号通知 CPU 有数据到达,CPU 执行中断程序(步骤 ③)

    此处的中断程序主要有两项功能,先将网络数据写入到对应 Socket 的接收缓冲区里面(步骤 ④),再唤醒进程 A(步骤 ⑤),重新将进程 A 放入工作队列中。

    唤醒进程的过程如下图所示:
    在这里插入图片描述

    3.5 进程阻塞为什么不消耗CPU?

    答:进程执行的过程的确是在内核CPU中执行的,会消耗CPU。但是当进程阻塞变成等待态的时候,会被加入该socket的等待队列中,并不会出现在内核中了,而是在socket的等待队列中“等待”。当进程被操作系统唤醒后,又会被加入到工作队列中。

    展开全文
  • 2、每个进程一个进程控制块( PCB)表示。进程控制块可以包含如下信息: 进程名---进程标示数 ID 优先数 PRIORITY 优先数越大优先权越高 到达时间---进程的到达时间为进程输入的时间。、 进程还需要运行时间ALL...
  • 进程简介 并发和并行并发:在一个时间段中多个程序都启动运行在用一个处理机中并行:两个进程分别由不同的CPU管理执行,两个进程不抢占CPU的资源,且可以同时运行,叫做并行区别在于是否同时多进程的优点各个进程有...
  • 有没有种方法可以查询Linux进程表中的进程状态,以便能够证明进程在查询时是运行还是阻塞执行?我的目标是从流程或程序的“外部”执行此操作,因为我希望通过操作系统流程了解这一点,但任何想法都是值得欢迎的!...
  • 来源:SegmentFault 思否社区作者:byte进程我们编写的代码只是一个存储在硬盘的静态文件,通过编译后就会生成二进制可执行文件,当我们运行这个可执行文件后,它会被装载到内存中,接着 CPU 会执行程序中的每一条...
  • 主要介绍了Python实现的服务器,结合实例形式分析了Python实现单进程、多进程、多线程、非阻塞式服务器的相关操作技巧,需要的朋友可以参考下
  • 线程系统调用阻塞是否导致进程阻塞的问题

    万次阅读 多人点赞 2018-01-04 16:21:45
    问题: 如果一个进程中的某一个线程调用了一个阻塞的系统调用函数后,那么该进程包括该进程中的其他所有线程也同时被阻塞 ? 关于这个问题。网上有些解答似乎比较混乱。回答这个问题,首先要简单了解一下线程模型。...
  • 一个进程(A)申请打印机但是此时打印机被其他进程(B)正在使用,此时A进程则处于阻塞状态。 等待某种操作的完成:进程A启动了某I/O设备,如果只有完成了指定的I/o任务后进程A才能执行,则进程A启动了I/O设备后会...
  • 文章目录同步(synchronous),异步(asynchronous)阻塞(blocking),非阻塞(non-blocking)(这里指系统的io操作)进程,线程,进程间通信的方式管道匿名管道(pipe)命名管道(FIFO)消息队列共享内存信号信号量socket...
  • 进程与线程 阻塞与非阻塞

    千次阅读 2018-04-16 20:22:34
    可以点很多菜(cpu中的进程):宫保鸡丁,鱼香肉丝,酸辣土豆丝。每样菜具体包含了哪些内容(cpu每个进程中的线程):宫保鸡丁(详情:黄瓜、胡萝卜、鸡肉、花生米)。而详情构成了宫保鸡丁这道菜,吃了以后不饿。就可以...
  • ffmpeg进程莫名阻塞,经过排查发现问题可能处在aac编码使用了固定码率导致,加上-qscale:a 4参数后得以解决
  • 查找阻塞进程sql

    2017-10-23 22:45:27
    查找阻塞进程sql的方法,查找阻塞进程sql的方法,减少死锁
  • SQLServer进程阻塞的检查和解决办法,有具体的代码,使用方便~
  • 关键字: Linux进程创建的实例 进程控制原语 进程阻塞和唤醒 进程的撤销 进程的挂起和激活
  • 进程创建、终止、阻塞、调度、唤醒原语有助于对操作系统中近程功能的了解,掌握操作系统模块的设计方法和工作原理
  • 多个进程没有办法做到同时写一个文件,解决这个问题的方法也很简单: import fcntl new_entry = "foobar" with open("/somepath/somefile.txt", "a") as g: fcntl.flock(g, fcntl.LOCK_EX) g.write(new_entry) ...
  • python进程阻塞

    千次阅读 2019-03-12 16:27:40
    from urllib import request import os from multiprocessing import Process ... print("进程A") def B(): print("进程B") if __name__ == '__main__': # 结束了最后执行 # p1=Process(target=A) #...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 443,801
精华内容 177,520
关键字:

一个进程可以阻塞其他进程吗