20190914

并发编程知识的整理

操作的系统的历史介绍

第一代计算机(1940~1955):真空管和插件板

第二代计算机(1955~1965):晶体管和批处理系统

第三代计算机(1965~1980):集成电路芯片和多道程序设计

多道技术 :多道技术中的多道指的是多个程序,多道技术的实现是为了解决多个程序竞争或者说共享同一个资源(比如cpu)的有序调度问题,解决方式即多路复用,多路复用分为时间上的复用和空间上的复用。

空间上的复用:将内存分为几部分,每个部分放入一个程序,这样,同一时间内存中就有了多道程序(共用一个内存条,多个进程互相隔离,物理级别隔离,程序与程序之间互不干扰

时间上的复用:当一个程序在等待I/O时,另一个程序可以使用cpu,如果内存中可以同时存放足够多的作业,则cpu的利用率可以接近100%,类似于我们小学数学所学的统筹方法。(操作系统采用了多道技术后,可以控制进程的切换,或者说进程之间去争抢cpu的执行权限。这种切换不仅会在一个进程遇到 io 时进行,一个进程占用cpu时间过长也会切换,或者说被操作系统夺走cpu的执行权限)共用一个cpu

分时操作系统:
多个联机终端+多道技术

串行:一个程序完完整整的执行完才能运行下一个程序

并发:看起来像在同时运行(单核),实际上也是串行,区别在于它不一定执行完整,中途在不停地切换

并行:同时执行多个程序

程序:躺在硬盘上的文件
进程:一个执行的程序,是一系列资源的总和

进程与程序区别:进程是正在进行的一个过程或者说一个任务,而程序仅仅仅只是一堆代码。

需要强调的是:同一个程序执行两次,那也是两个进程,比如打开暴风影音,虽然都是同一个软件,但是一个可以播放苍井空,一个可以播放饭岛爱。

进程的三个基本状态

进程执行时的间断性,决定了进程可能具有多种状态。事实上,运行中的进程可能具有以下三种基本状态。
就绪状态(Ready):

进程已获得除处理器外的所需资源,等待分配处理器资源;只要分配了处理器进程就可执行。就绪进程可以按多个优先级来划分队列。例如,当一个进程由于时间片用完而进入就绪状态时,排入低优先级队列;当进程由I/O操作完成而进入就绪状态时,排入高优先级队列。
运行状态(Running):
进程占用处理器资源;处于此状态的进程的数目小于等于处理器的数目。在没有其他进程可以执行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程。
阻塞状态(Blocked):
由于进程等待某种条件(如I/O操作或进程同步),在条件满足之前无法继续执行。该事件发生前即使把处理器资源分配给该进程,也无法运行

尽量减少阻塞状态可以提升我们程序运行的效率

并发 = 保存状态+切换

开启子进程 申请新的内存空间 把父进程的所有代码完整拷贝一份过去

# from multiprocessing import Process
# def task(x):
#     pass
#
# if __name__ == '__main__':
#     p = Process(target=task,args=(45,))
#     p.start()

第二种开启子进程的方式(不常用)

# from multiprocessing import Process
#
#
# class Xx(Process):
#     def __init__(self,x):
#         super().__init__()
#         self.x = x
#     def run(self):
#         pass
#
#
# p = Xx()
# p.start()

僵尸进程:父进程的子进程结束的时候父进程没有wait()情况下子进程会变成僵尸进程。(父进程一直不死不停造子进程并且不回收僵尸进程有害)

父进程等着所有的子进程结束才会结束。

孤儿进程(无害)

一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

情况1 无害
父进等着子进程都死,回收僵尸进程。

情况2 无害
父进程死了,子进程活着,都要被init进程接管并且回收。

情况3 有害
父进程一直不死,造成了大量僵尸进程。占用了大量的pid号

pid号是有限的。
解决方案:
最直接的办法就是杀死父进程 。

20190915

Process中join方法

join:阻塞住主进程再等待子进程结束,然后再往下执行,

具体代码如下:

from multiprocessing import Process
import time
def foo():time.sleep(4)print('进程  start ')time.sleep(5)print('进程  end ')if __name__ == '__main__':p = Process(target=foo)p.start() #p.join(3) # 阻塞住主进程再等待子进程结束,然后再往下执行,(了解的是:内部会待用wait())print('主')

p.join(3):括号内的数字代表阻塞的时间

多个join的情况,代码如下

from multiprocessing import Process
import time
def task(n):print('子进程 开始')time.sleep(n)print('子进程 结束')
if __name__ == '__main__':start_time = time.time() # 记录开始时间p1 = Process(target=task,args=(2,))p2 = Process(target=task,args=(4,))p3 = Process(target=task,args=(6,))p1.start()p2.start()p3.start()# 换顺序也是一样的也是按照时长最长的那个计算。p1.join() # 等待2sp2.join() # 等待2sp3.join() # 等待2send_time = time.time() # 记录结束时间print(end_time-start_time) # 计算时间差print('主线程')子进程 开始子进程 开始子进程 开始子进程 结束子进程 结束子进程 结束7.566513776779175主线程

join串行的情况

from multiprocessing import Process
import time
def task(n):print('子进程 开始')time.sleep(n)print('子进程 结束')
if __name__ == '__main__':start_time = time.time() # 记录开始时间p1 = Process(target=task,args=(2,))p2 = Process(target=task,args=(4,))p3 = Process(target=task,args=(6,))p1.start()p1.join() p2.start()p2.join() p3.start()p3.join() end_time = time.time() # 记录结束时间print(end_time-start_time) # 计算时间差print('主线程')'''输出:子进程 开始子进程 结束子进程 开始子进程 结束子进程 开始子进程 结束15.407774925231934主线程'''# ps:反而不如不开进程,正常调用三次来的快。

精炼代码:

from multiprocessing import Process
import time
def task(n):print('子进程 开始')time.sleep(n)print('子进程 结束')
if __name__ == '__main__':start_time = time.time() # 记录开始时间task_list = []for i in range(1,4):p = Process(target=task,args=(i,))p.start()task_list.append(p)print(task_list) # [<Process(Process-1, started)>, <Process(Process-2, started)>, <Process(Process-3, started)>]for i in task_list:i.join()end_time = time.time() # 记录结束时间print(end_time-start_time) # 计算时间差 4.764175891876221print('主线程')

pid的用法

在当前进程查看当前进程pidos.getpid()current_process().pid
在当前进程查看子进程pid子进程对象.pid()
在当前进程查看父进程pidos.getppid() from multiprocessing import Process,current_process
import time,osdef task():print('子进程 start')print('在子进程中查看自己的pid',current_process().pid) # 在子进程中查看自己的pidprint('在子进程中查看父进程的pid',os.getppid()) #time.sleep(200)print('子进程 end')if __name__ == '__main__':p = Process(target=task)p.start()print('在主进程查看子进程的pid',p.pid) # 一定要写在 start()之后print('主进程的pid',os.getpid())print('主进程的父进程pid',os.getppid())print('主')

name的用法:

from multiprocessing import Process,current_processdef task():print(current_process().name) # 在子进程查看自己的nameif __name__ == '__main__':p = Process(target=task) p2 = Process(target=task)p3 = Process(target=task,name='rocky') # 已定义name属性为rockyp.start()p2.start()p3.start()print(p.name) #Process-1print(p2.name) #Process-2print(p3.name) #rocky

is_alive用法:

from multiprocessing import Process,current_process
import time
def task():print('子进程开始')time.sleep(1)print('子进程结束')if __name__ == '__main__':p = Process(target=task)p.start()# p.terminate() #发送一个指令给操作系统但是不会立即结束子进程# time.sleep(1)print(p.is_alive()) # True 判断子进程代码是否结束time.sleep(3)print(p.is_alive()) # False

守护进程:

主进程创建守护进程

  其一:守护进程会在主进程代码执行结束后就终止

  其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children

什么情况适合用守护进程?

当主进程代码结束,该子进程再执行无意义的情况可以用守护进程。

具体代码如下

例一:主进程代码运行完,守护进程立即结束

from multiprocessing import Process
import time
def foo():print('守护进程开始')time.sleep(5)print('守护进程开始')if __name__ == '__main__':p1 = Process(target=foo)p1.daemon = True # 一定要凡在start之前,表示设置为一个守护进程。p1.start()print('主进程')'''输出:主进程'''# 守护进程一旦发现主进程代码运行完,立刻结束,并不会管自己的进程是否运行完

例二 主进程代码运行完后等在子进程运行阶段,线程不会参与守护

from multiprocessing import Processimport time
def foo():print('守护进程开始')time.sleep(5)print('守护进程结束')
def task():print('子进程开始')time.sleep(3)print('子进程开始')if __name__ == '__main__':p1 = Process(target=foo)p2 = Process(target=task)p1.daemon = True # 一定要凡在start 之前p1.start()p2.start()# p2 = Process(target=task)print('主进程')'''输出:主进程子进程开始子进程开始'''#分析 守护进程在运行完主进程最后一行代码就结束,但是主进程并没有结束,主进程在等待子进程运行结束.

转载于:https://www.cnblogs.com/asyouwish/p/11522437.html

并发编程知识的简单整理(一)相关推荐

  1. 并发编程知识总结,软件开发架构,socket套接字模板,粘包问题,struct解决粘包问题,上传大文件数据,socketserver,关于操作系统的发展史,进程,线程。...

    并发编程知识总结 软件开发架构 C/S: client:客户端 server:服务端 优点:占用网络资源少,软件的使用稳定 缺点:服务端更新后,客户端也要更新,需要使用多个软件,需要下载多个客户端 B ...

  2. 奉劝那些刚参加工作的学弟学妹们:要想进大厂,这些并发编程知识是你必须要掌握的!完整学习路线!!(建议收藏)

    大家好,我是冰河~~ 今天给大家带来一篇完整的并发编程学习路线,这应该是全网最全的并发编程学习路线了吧,希望能够为各位小伙伴们带来实质性的帮助. 如果这篇文章对大家有点帮助,小伙伴们点赞,收藏,评论, ...

  3. 并发编程——JUC并发编程知识脑图

    摘要 并发编程在软件编程中尤为突出和重要,在当今面试或工作中也是不可缺少的.作为一名高级java开发工程师,并发编程的技能已经成为了重要的一项.本博文将详细介绍并发编程中的知识点和知识脑图,帮助大家更 ...

  4. Java多线程并发编程知识体系(附大图-持续更新)

    Java多线程体系 1.并发编程的优势 提升CPU资源利用率 提升吞吐量 提升程序响应速度 更好的编程模型 2.并发带来的问题 1.安全性问题 0.定义:什么是安全性问题 多线程读写共享变量时出现不正 ...

  5. 高并发编程知识体系阅读总结

    高并发编程在软件开发中具有非常重要的作用,它是微观上的性能调优, 首先并发是一个处理器同时处理多个任务 并行是多个处理器或者是多核的处理器同时处理多个不同的任务 同步是执行某个操作开始后就一直等着按部 ...

  6. 120000字,你们要的Java 并发编程图文小册整理出来了,免费送给大家!

    Java 有并发,并发知识之大,一口吃不下 这曾是我不愿意触碰的知识角 多次一头扎进并发,无功而返 为应对面试,临时苦苦记忆,不成体系 这一次我决定从基础开始,攻克它 12,0000 字 68Mb 高 ...

  7. Java并发编程知识大汇总

    线程简介 什么是线程 现代操作系统调度的最小单元是线程,也叫轻量级进程,在一个进程里可以创建很多是线程,这些线程都有自己的计数器,堆栈和局部变量等属性,并且能够访问共享的内存变量. 之所以我们感觉不到 ...

  8. 【并发编程】volatile简单使用

    Atomic 以更为轻量的方式实现原子性..本次我们学习 volatile 关键字,则是用来解决可见性.有序性问题. 简介 在 JDK1.2 之前,Java的内存模型实现总是从主存(即共享内存)读取变 ...

  9. Java并发编程知识总结

    一.线程 1.线程创建: 继承Thread类创建线程类 实现Runnable接口创建线程类 使用Callable和Future创建线程 Runnable是执行工作的独立任务,但是它不返回任何值,如果希 ...

最新文章

  1. rabbitmq 启动报错 Failed to get nic info
  2. 我们用4行代码节省了100万 记录与阿里云PCDN相遇全过程
  3. 算法竞赛入门经典 第二章总结
  4. 小程序 const moment = require('moment')_小程序依赖分析实践
  5. 分子机制研究的五个层次,你的研究在哪个层次--转载
  6. php字符集转换,php字符集转换
  7. java预览表格预览文档_java 如何创建一个表格.docx
  8. 生成对抗网络GAN损失函数loss的简单理解
  9. 2个相同的 stm32 can通讯不成功_STM32芯片的几种烧写方式简介
  10. PDF如何加水印? PDF加水印的方法
  11. html5中nav标签(导航链接)的详细介绍
  12. python中访问列表元素具体格式_Python3基础 list 访问列表中的列表的元素
  13. 如何运用时间管理四象限法则去管理时间?
  14. 2021年C/C++Linux服务器开发/后台架构师知识体系整理(持续更新中)
  15. 重要消息|2020年9月1日起, SSL证书最长有效期变更为1年
  16. co作为前缀的意思_品牌故事之Tiffany Co
  17. cublas_学习笔记2
  18. 云计算原理与实践 第一章、云计算概述
  19. 你的论文题目确定了吗
  20. Vscode上使用opencv(C++接口,Windows篇)

热门文章

  1. linux cpu gonvor,LWN:Linux 5.1使用TEO governor来代替cpuidle menu governor
  2. gstreamer学习笔记---demux使用
  3. Oracle与SAP两种ERP六维度比拼
  4. 如何查国内学术会议(国内会议论文投稿)
  5. CSS文字居中显示的几种方式
  6. JSM 2019 | 数据驱动在滴滴,详解智能出行时代的统计思维
  7. UnityRPG游戏中的球形检测范围
  8. Java直接杀死线程方法_如何杀死一个线程?
  9. 数字孪生工厂生产线系统构建与应用
  10. 给mysql salve从库复制授权_MySQL主从复制 - osc_h8z06jiq的个人空间 - OSCHINA - 中文开源技术交流社区...