Python之旅.第九章.并发编程

进程

#串行: 一个一个的运行

1、什么是程序?什么是进程?

程序说白了就是一堆文件

进程就是一个正在执行的过程/程序,所以说进程是一个抽象的概念。这个概念起源操作系统

2、什么是操作系统

定义:操作系统是位于计算机硬件与应用软件之间,用于协调、管理、控制计算机硬件与软件的资源的一种控制程序

3、操作系统的两大作用:

1、把复杂丑陋的硬件操作都封装成美丽的接口,提供给应用程序使用

2、把进程对硬件的竞争变的有序

4、多道技术(单个CPU在多个程序中切换以实现并发)

多道的产生背景是想要在单个cpu的情况下实现多个进程并发执行的效果

a、空间上的复用 (多道程序复用内存的空间)

b、时间上的复用  (多道程序复用CPU时间)

cpu遇到IO操作要切换(提升效率)

一个进程占用cpu时间过长也切(降低效率)

进程与进程之间的内存空间是互相隔离的

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 15.0px; font: 13.0px "PingFang SC"; color: #000066; background-color: #ffffff }
p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 15.0px; font: 13.0px Courier; color: #000066; background-color: #ffffff }
p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 15.0px; font: 13.0px Courier; color: #000066; background-color: #ffffff; min-height: 16.0px }
span.s1 { }
span.s2 { font: 13.0px Courier }
span.s3 { font: 13.0px "PingFang SC" }

并发的本质:切换+保持状态

一、同一个程序执行多次是多个进程

每一个进程有一个PID

import os

print(‘爹是:‘,os.getppid())    #父的pid (pycharm.exe)

print(‘me是: ‘,os.getpid())     #自己的pid (python.exe)

二、开启子进程的两种方式

windows (createprocess) 创建子进程时子辈除了拷贝父辈的信息还创建了些自己的东西

unix (fork) 创建子进程时拷贝父辈的信息,子进程的初始状态和父辈一致

第一种(比较常用)

from multiprocessing import Process

import time

def task(name):

print(‘%s is running‘ %name)

time.sleep(3)

print(‘%s is done‘ %name)

if __name__ == ‘__main__‘:

# 在windows系统之上,开启子进程的操作一定要放到这下面

# Process(target=task,kwargs={‘name‘:‘egon‘})   #两种传参方式皆可

p=Process(target=task,args=(‘egon‘,))          #两种传参方式皆可

p.start() # 向操作系统发送请求,操作系统会申请内存空间,然后把父进程的数据拷贝给子进程,作为子进程的初始状态

print(‘======主‘)

第二种

from multiprocessing import Process

import time

class MyProcess(Process):

def __init__(self,name):

super(MyProcess,self).__init__()     #Process在init里面有相应设置,要遗传下来,否则报错

self.name=name

def run(self):

print(‘%s is running‘ %self.name)

time.sleep(3)

print(‘%s is done‘ %self.name)

if __name__ == ‘__main__‘:

p=MyProcess(‘egon‘)

p.start()   #p.start()调用了类中的run()方法(规定)

print(‘主‘)

三、进程的内存空间相互隔离

from multiprocessing import Process

import time

x=1000

def task():

time.sleep(3)

global x

x=0

print(‘儿子死啦‘,x)

#在之前最好只有函数或变量的定义,没有具体的执行(print等)

if __name__ == ‘__main__‘:

p=Process(target=task)

p.start()

time.sleep(5)

print(x)

#在子进程中对变量x的修改不影响父进程中x的值

四、父进程等待子进程结束 p1.join()

#笨

from multiprocessing import Process

import time

x=1000

def task(n):

print(‘%s is runing‘ %n)

time.sleep(n)

if __name__ == ‘__main__‘:

start_time=time.time()

p1=Process(target=task,args=(1,))

p2=Process(target=task,args=(2,))

p3=Process(target=task,args=(3,))

p1.start()

p2.start()

p3.start()

p3.join() #3s

p1.join()

p2.join(    )

print(‘主‘,(time.time() - start_time))        #3.01637601852417

#用循环

from multiprocessing import Process

import time

x=1000

def task(n):

print(‘%s is runing‘ %n)

time.sleep(n)

if __name__ == ‘__main__‘:

start_time=time.time()

p_l=[]

for i in range(1,4):

p=Process(target=task,args=(i,))

p_l.append(p)

p.start()

for p in p_l:

p.join()

print(‘主‘,(time.time() - start_time))       #3.0141923427581787

五、进程对象的其他属性

from multiprocessing import Process

import time

def task(n):

print(‘%s is runing‘ %n)

time.sleep(n)

if __name__ == ‘__main__‘:

start_time=time.time()

p1=Process(target=task,args=(1,),name=‘任务1‘)

p1.start()

print(p1.pid)

print(p1.name)     #如前面不定义name,默认process-1 etc

p1.terminate()     #向操作系统发请求,关闭需要一点时间

p1.join()

print(p1.is_alive())

print(‘主‘)

from multiprocessing import Process

import time,os

def task():

print(‘self:%s parent:%s‘ %(os.getpid(),os.getppid()))

time.sleep(3)

if __name__ == ‘__main__‘:

p1=Process(target=task,)

p1.start()

print(p1.pid)

print(‘主‘,os.getpid())

六、僵尸进程与孤儿进程

在unix系统中init是所有进程的爹;创建进程用fork,回收进程用waitpid

僵尸进程(有害:占用pid):子代先于父代终结,其部分信息(pid等)没有从系统中删除,需要父代回收。join中含有回收子代信息的功能。

孤儿进程(无害):父代先于子代终结,子代终结后的部分信息由init代收。

from multiprocessing import Process

import time,os

def task(n):

print(‘%s is running‘ %n)

time.sleep(n)

if __name__ == ‘__main__‘:

p1=Process(target=task,args=(1,))

p1.start()

p1.join()     # join中含有回收子代信息的功能(wait)

print(‘======主‘,os.getpid())

time.sleep(10000)

原文地址:https://www.cnblogs.com/yangli0504/p/8930957.html

时间: 2024-10-24 00:03:16

Python之旅.第九章.并发编程的相关文章

Python之旅.第九章.并发编程。

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 15.0px; font: 13.0px "PingFang SC"; color: #000066; background-color: #ffffff } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 15.0px; font: 13.0px Courier; color: #000066; background-co

《Programming in Go》第七章并发编程译文

中文译名 Go 编程 外文原文名 Programming in Go 外文原文版出处 the United States on recycled paper at RR Donnelley in Crawfordsville, Indiana. 译 文: 第七章 并发编程 7.1主要概念 7.2例子 7.2.1:过滤器 7.2.2:并发查找 7.2.3:线程安全表 7.2.4:Apache 报告 7.2.5:找重复 并发编程能够让开发者实现并行算法,以及利用多处理器和多核写程序.但是在大多主流变

[CSAPP笔记][第十二章并发编程]

第十二章 并发编程 如果逻辑控制流在时间上是重叠,那么它们就是并发的(concurrent).这种常见的现象称为并发(concurrency). 硬件异常处理程序,进程和Unix信号处理程序都是大家熟悉的例子. 我们主要将并发看做是一种操作系统内核用来运行多个应用程序的机制. 但是,并发不仅仅局限于内核.它也可以在应用程序中扮演重要的角色. 例如 Unix信号处理程序如何允许应用响应异步事件 例如:用户键入ctrl-c 程序访问虚拟存储器的一个未定义的区域 其他情况 访问慢速I/O设备 当一个应

第十二章 并发编程 学习笔记

第十二章 并发编程 进程是程序级并发,线程是函数级并发. 三种基本的构造并发程序的方法: 进程:每个逻辑控制流是个一个进程,由内核进行调度和维护. I/O多路复用:应用程序在一个进程的上下文中显式地调度他们自己的逻辑流. 线程:运行在单一进程上下文中的逻辑流,由内核进行调度. 12.1 基于进程的并发编程 构造并发程序最简单的方法就是用进程. 使用大家都很熟悉的函数例如: fork exec waitpid 关于在父.子进程间共享状态信息:共享文件表,但不共享用户地址空间. 进程又独立的地址空间

第十二章 并发编程

第十二章 并发编程 三种基本的构造并发程序 进程:每个逻辑控制流是一个进程,由内核进行调度,进程有独立的虚拟地址空间 I/O多路复用:逻辑流被模型化为状态机,所有流共享同一个地址空间 线程:运行在单一进程上下文中的逻辑流,由内核进行调度,共享同一个虚拟地址空间 常用函数: fork exec waitpid 基于I/O多路复用的并发事件驱动服务器 事件驱动程序:将逻辑流模型化为状态机. 状态机: 状态 输入事件 转移 对于状态机的理解,参考EDA课程中学习的状态转换图的画法和状态机. 整体的流程

C Primer Plus (第五版) 第九章 函数 编程练习

第九章 函数 编程练习 设计函数 min(x,y),返回两个double数值中较小的数值,同时用一个简单的驱动程序测试该函数. #include <stdio.h> double min(double x, double y); int main(void) { double a, b; printf("请输入两个数:\n"); scanf("%lf%lf", &a, &b); printf("两个数中较小的数是:%lf\n&q

第十五章 并发编程

1.操作系统的发展史 参考:http://www.cnblogs.com/Eva-J/articles/8253521.html 知识点 输入输出 -- 大部分时间都不会占用CPU,但会降低你程序的效率 操作系统的三种基本类型:多道批处理系统.分时系统.实时系统. 现在操作系统 基于多道批处理系统和分时系统 多个程序.作业在遇到IO操作的时候,操作系统会帮助你进行切换 让CPU的利用率得到最大的提高 2.进程 初识进程 进程: 运行中的程序 操作系统 只负责管理调度进程 进程是操作系统中资源分配

第一章 并发编程的挑战

挑战一:上下文切换 多线程一定比单线程快么? public class ConcurrencyTest { private static final long count = 10001; public static void main(String[] args) throws InterruptedException { concurrency(); serial(); } private static void concurrency() throws InterruptedExcepti

深入理解计算机系统 第十二章 并发编程

如果逻辑控制流在时间上重叠,那么它们就是并发的(concurrent) 这种常见的现象称为并发(concurrency),出现在计算机系统的许多不同层面上. 并发不仅仅局限于内核,它也可以在应用程序中扮演重要角色. 应用级并发在以下情况中都是很有用的: 1.访问慢速 I/O 设备 当一个应用正在等待来自慢速 I/O 设备(例如磁盘)的数据到达时,内核会运行其它进程,使 CPU 保持繁忙.每个应用都可以按照类似的方式,通过交替执行 I/O 请求和其他有用的工作来利用并发. 2.与人交互 和计算机交