I/O复用模型

I/O复用原理:让应用程序可以同时对多个I/O端口进行监控以判断其上的操作是否可以进行,达到时间复用的目的。在书上看到一个例子来解释I/O的原理,我觉得很形象,如果用监控来自10根不同地方的水管(I/O端口)是否有水流到达(即是否可读),那么需要10个人(即10个线程或10处代码)来做这件事。如果利用某种技术(比如摄像头)把这10根水管的状态情况统一传达到某一点,那么就只需要1个人在那个点进行监控就行了,而类似与select或epoll这样的多路I/O复用机制就好比是摄像头的功能,它们能够把多个I/O端口的状况反馈到同一处,比如某个特定的文件描述符上,这样应用程序只需利用对应的select()或epoll_wait()系统调用阻塞关注这一处即可。

I/O多路复用的优劣:由于I/O多路复用是在单一进程的上下文中的,因此每个逻辑流程都能访问该进程的全部地址空间,所以开销比多进程低得多;缺点是编程复杂度高。

多进程模型

构造并发最简单的就是使用进程,像fork函数。例如,一个并发服务器,在父进程中接受客户端连接请求,然后创建一个新的子进程来为每个新客户端提供服务。
 

优点

  1. 每个进程互相独立,不影响主程序的稳定性,子进程崩溃没关系;
  2. 通过增加CPU,就可以容易扩充性能;
  3. 可以尽量减少线程加锁/解锁的影响,极大提高性能,就算是线程运行的模块算法效率低也没关系;
  4. 每个子进程都有2GB地址空间和相关资源,总体能够达到的性能上限非常大

缺点

  1. 逻辑控制复杂,需要和主程序交互;
  2. 需要跨进程边界,如果有大数据量传送,就不太好,适合小数据量传送、密集运算
  3. 多进程调度开销比较大;

多线程模型

每个线程都有自己的线程上下文,包括一个线程ID、栈、栈指针、程序计数器、通用目的寄存器和条件码。所有的运行在一个进程里的线程共享该进程的整个虚拟地址空间。由于线程运行在单一进程中,因此共享这个进程虚拟地址空间的整个内容,包括它的代码、数据、堆、共享库和打开的文件。

线程和进程的执行模型有些相似,每个进程的声明周期都是一个线程,我们称之为主线程。线程是对等的,主线程跟其他线程的区别就是它先执行。

 

优点

  1. 无需跨进程边界;
  2. 程序逻辑和控制方式简单;
  3. 所有线程可以直接共享内存和变量等;
  4. 线程方式消耗的总资源比进程方式好;

缺点

  1. 每个线程与主程序共用地址空间,受限于2GB地址空间;
  2. 线程之间的同步和加锁控制比较麻烦;
  3. 一个线程的崩溃可能影响到整个程序的稳定性;
  4. 到达一定的线程数程度后,即使再增加CPU也无法提高性能,例如Windows Server 2003,大约是1500个左右的线程数就快到极限了(线程堆栈设定为1M),如果设定线程堆栈为2M,还达不到1500个线程总数;
  5. 线程能够提高的总性能有限,而且线程多了之后,线程本身的调度也是一个麻烦事儿,需要消耗较多的CPU
 
Linux的线程实现是在核外进行的,核内提供的是创建进程的接口do_fork()。内核提供了两个系统调用__clone()和fork(),最终都用不同的参数调用do_fork()核内API。 do_fork() 提供了很多参数,包括CLONE_VM(共享内存空间)、CLONE_FS(共享文件系统信息)、CLONE_FILES(共享文件描述符表)、CLONE_SIGHAND(共享信号句柄表)和CLONE_PID(共享进程ID,仅对核内进程,即0号进程有效)。当使用fork系统调用产生多进程时,内核调用do_fork()不使用任何共享属性,进程拥有独立的运行环境。当使用pthread_create()来创建线程时,则最终设置了所有这些属性来调用__clone(),而这些参数又全部传给核内的do_fork(),从而创建的”进程”拥有共享的运行环境,只有栈是独立的,由 __clone()传入。
即:Linux下不管是多线程编程还是多进程编程,最终都是用do_fork实现的多进程编程,只是进程创建时的参数不同,从而导致有不同的共享环境。Linux线程在核内是以轻量级进程的形式存在的,拥有独立的进程表项,而所有的创建、同步、删除等操作都在核外pthread库中进行。pthread 库使用一个管理线程(__pthread_manager() ,每个进程独立且唯一)来管理线程的创建和终止,为线程分配线程ID,发送线程相关的信号,而主线程pthread_create()) 的调用者则通过管道将请求信息传给管理线程。

IO复用、多进程和多线程三种并发编程模型的更多相关文章

  1. 4、Java并发性和多线程-并发编程模型

    以下内容转自http://ifeve.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B%E6%A8%A1%E5%9E%8B/: 并发系统可以采用多种并发编程模型来实现. ...

  2. java 多线程——并发编程模型 学习笔记

                                                                                                 并发编程模型 ...

  3. SQL2000的三种“故障还原模型”

    一.SQL2000的三种“故障还原模型” 在数据库属性的“选项”页,“故障还原模型”栏,共有三项选择:简单.完全.大容量日志记录.它们的根本差别在于SQL2000对数据库日志的维护方式不同.下面逐个讲 ...

  4. Scala进阶之路-并发编程模型Akka入门篇

    Scala进阶之路-并发编程模型Akka入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Akka Actor介绍 1>.Akka介绍 写并发程序很难.程序员不得不处 ...

  5. Java并发编程的艺术读书笔记(2)-并发编程模型

    title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1 ...

  6. Reactor 模型(一)基本并发编程模型

    Reactor 模型(一)基本并发编程模型 Netty 系列目录 (https://www.cnblogs.com/binarylei/p/10117436.html) 在讲解 Reactor 线程模 ...

  7. Scala并发编程模型AKKA

    一.并发编程模型AKKA Spark使用底层通信框架AKKA 分布式 master worker hadoop使用的是rpc 1)akka简介 写并发程序很难,AKKA解决spark这个问题. akk ...

  8. python万能消费框架,新增7种中间件(或操作mq的包)和三种并发模式。

    新增的中间件和并发模式见注释. 消息队列中间件方面celery支持的,都要支持.并发模式,celery支持的都要支持. 从无限重复相似代码抽取框架,做成万能复用,是生产力的保障. 使用模板模式使加新中 ...

  9. JAVA基础知识之多线程——三种实现多线程的方法及区别

    所有JAVA线程都必须是Thread或其子类的实例. 继承Thread类创建线程 步骤如下, 定义Thead子类并实现run()方法,run()是线程执行体 创建此子类实例对象,即创建了线程对象 调用 ...

随机推荐

  1. BZOJ1432_Function_KEY

    题目传送门 找规律. 画一个像这样的图: 不同颜色为不同层,因为函数图像可对称,所以只考虑K<=N/2的情况. 最小为min(K,N-K+1)*2. N=1时特殊考虑,答案为1. code: # ...

  2. 2017Noip普及组游记

    Day0 一天都基本在休息,早上信心赛,大家都是400整. 下午一群人窝在教室里打三国杀. Day1:Before Contest 早上大约十点到了试场,在考提高组,不能进. 喝了一杯咖啡去除早起的身 ...

  3. 成都Uber优步司机奖励政策(3月11日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  4. web漏洞原理 (需要每周更新此篇文章)

    SQL注入攻击简介 结构化查询语言SQL是用来和关系数据库进行交互的文本语言.它允许用户对数据进行有效的管理,包含了对数据的查询.操作.定义和控制等几个方面,例如向数据库写入.插入数据,从数据库读取数 ...

  5. 180611-Spring之RedisTemplate配置与使用

        logo 文章链接:https://liuyueyi.github.io/hexblog/2018/06/11/180611-Spring之RedisTemplate配置与使用/ Spring ...

  6. Web应用服务器性能压力测试

    压力测试需要关注三个方面:如何正确产生压力.如何定位瓶颈.如何预估系统的承载能力 产生压力的方法 通常可以写脚本产生压力机器人对服务器进行发包和收包操作,也可以使用现有的工具(像jmeter.Load ...

  7. leetcode-分割回文子串

    给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. 示例: 输入: "aab" 输出: [ ["aa",&quo ...

  8. 理解Python中的__builtin__和__builtins__

    以Python 2.7为例,__builtin__模块和__builtins__模块的作用在很多情况下是相同的. 但是,在Python 3+中,__builtin__模块被命名为builtins. 所 ...

  9. error:no module named StringIO or cStringIO

    一般遇到没有某个模块问题的时候,通常的解决方法是pip相应的模块: 不过,鉴于Python2和python3的不同(让人头疼) 解决方法:在python3中,该模块被新的模块取代,即io. 重新imp ...

  10. windows store无法登陆的问题解决方案

    Windows应用商店或商店Apps无法打开或闪退的可选方法 (仅用于10565之前的Windows 10版本) 右键点击任务栏,选择"属性",切换到"导航"选 ...