Python并发编程

并发编程

1. 操作系统的发展史

学习并发编程其实就是在学习操作系统的发展史(底层逻辑),计算机操作系统经历过以下三种时代

  1. 穿孔卡片时代

    ​ CPU的利用率极低

    img

  2. 联机批处理系统

    ​ 将多个程序员的程序一次性录入磁带中,之后交由输入机输入并由CPU执行

  3. 脱机批处理系统

    ​ 现在计算机的雏形(远程输入 高速磁带 主机)

    img

2. 多道技术

多道技术的前提是 : 单核CPU

多道技术的本质是 : 所谓多道程序设计技术,就是指允许多个程序同时进入内存并运行。即同时把多个程序放入内存,并允许它们交替在CPU中运行,它们共享系统中的各种硬、软件资源。当一道程序因I/O请求而暂停运行时,CPU便立即转去运行另一道程序。

多道技术的核心是 : CPU的快速切换+保存状态

CPU的工作机制

  1. 当某个程序进入IO状态的时候 操作系统会自动剥夺该程序的CPU执行权限
  2. 当某个程序长时间占用CPU的时候 操作系统也会剥夺该程序的CPU执行权限

img

img

3. 进程理论

# 进程与程序的区别
	程序:一堆代码(死的)
    进程:正在运行的程序(活的)
        
# 单核情况下的进程调度
	进程调度算法演变
    	1.FCFS	先来先服务
        	对短作业不友好
        2.短作业优先调度算法
        	对长作业不友好
        3.时间片轮转法+多级反馈队列
        	先分配给新的多个进程相同的时间片
            之后根据进程消耗的时间片多少分类别......
            
# 进程三状态图(******)
	就绪态 运行态 阻塞态
    就绪(Ready)状态:当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态。

  执行/运行(Running)状态:当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态。

  阻塞(Blocked)状态:正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。
    	进程要想进入运行态必须先经过就绪态            

在这里插入图片描述

img
在这里插入图片描述

# 并行与并发(******)
	并行:多个程序同时执行
    并发:多个程序只要看起来像同时运行即可
# 同步与异步(******)
	'''用于描述任务的提交方式'''
	同步:提交完任务之后原地等待任务的返回结果 期间不做任何事
    异步:提交完任务之后不原地等待任务的返回结果 直接去做其他事 结果由反馈机制自动提醒
        
# 阻塞与非阻塞(******)
	'''用于描述任务的执行状态'''
    阻塞:阻塞态
    非阻塞:就绪态 运行态        
        
同步/异步与阻塞/非阻塞
	组合效率:
        异步非阻塞形式 > 同步非阻塞形式 > 异步阻塞形式 > 同步阻塞形式

4. 创建进程

创建进程需要 multiprocess.process 模块

process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建。

Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)

强调:
1. 需要使用关键字的方式来指定参数
2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号

参数介绍:
1 group参数未使用,值始终为None
2 target表示调用对象,即子进程要执行的任务
3 args表示调用对象的位置参数元组,args=(1,2,'tom',)
4 kwargs表示调用对象的字典,kwargs={'name':'tom','age':18}
5 name为子进程的名称
# 代码层面创建进程
方式1:
from multiprocessing import Process
import time
import os


def test(name):
    print(os.getpid())  # 获取进程号
    print(os.getppid())  # 获取父进程号
    print('%s正在运行' % name)
    time.sleep(3)
    print('%s已经结束' % name)


if __name__ == '__main__':
    p = Process(target=test, args=('jason',))  # 生成一个进程对象
    p.start()  # 告诉操作系统开设一个新的进程     异步提交
    print(os.getpid())
    print('主')
    
"""
在windows中开设进程类似于导入模块
    从上往下再次执行代码
一定需要在__main__判断语句内执行开设进程的代码

在linux中是直接将代码完整的复制一份执行
    不需要在__main__判断语句内执行
"""

方式2:
class MyProcess(Process):
    def __init__(self, name):
        super().__init__()
        self.name = name

    def run(self):
        print('%s正在运行' % self.name)
        time.sleep(3)
        print('%s已经结束' % self.name)

if __name__ == '__main__':
    p = MyProcess('jason')
    p.start()
    print('主')

img

5. 进程的join方法

对象方法

1 p.start():启动进程,并调用该子进程中的p.run() 
2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法  
3 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
4 p.is_alive():如果p仍然运行,返回True
5 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程  
6 current_process 查看进程号
7 os.getpid() 查看进程号  os.getppid() 查看父进程进程号
from multiprocessing import Process
import time


def test(name, n):
    print('%s is running' % name)
    time.sleep(n)
    print('%s is over' % name)


if __name__ == '__main__':
    p_list = []
    start_time = time.time()
    for i in range(1, 4):
        p = Process(target=test, args=(i, i))
        p.start()
        p_list.append(p)
        # p.join()  # 串行  9s+
    for p in p_list:
        p.join()
    print(time.time() - start_time)

6. 进程间默认无法交互

# 进程间数据是相互隔离的
from multiprocessing import Process

money = 100


def test():
    global money
    money = 999


if __name__ == '__main__':
    p = Process(target=test)
    p.start()
    # 先确保子进程运行完毕了 再打印
    p.join()
    print(money)   # 100
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

go&Python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值