首页 > 技术文章 > Python3 并发编程1

bigb 2019-10-21 20:48 原文

操作系统发展

穿孔卡片

  • 一个计算机机房, 一次只能被一个卡片使用

批处理

  • 将一批作业提交给操作系统后就不再干预,由操作系统控制它们自动运行

  • 联机批处理系统: 在主机与输入机之间增加一个存储设备--磁带

  • 脱机批处理系统: 增加一台不与主机相连而专门用于与输入/输出设备打交道的卫星机

多道技术(单核)

  • 单道: 计算机内存中只运行一个程序
  • 多道: 计算机内存中穿插运行多个程序
    1. 当前执行程序遇到I/O操作, CPU会转而运行其他程序
    2. 当前程序占用CPU时间过长, CPU也会运行其他程序
    3. 优点: 提高CPU的利用率
    4. 缺点: 程序的执行效率降低

并发与并行

  • 并发: 在一个时间段内有多个程序在运行(分时交替)
  • 并行: 在一个时间点有多个程序在运行

进程

程序与进程

  • 程序: 有序的指令和数据的集合
  • 进程: 程序关于某个数据集合的一次运行活动, 是系统进行资源分配和调度的基本单位

进程调度

  • 先来先服务: 哪个进程先就绪就占用CPU, 进程阻塞或结束让出CPU
  • 短作业优先: 预计执行时间短的进程优先
  • 时间片轮转: 进程在就绪队列的等待时间与享受服务的时间成正比
  • 多级反馈队列: 设置多个就绪队列, 分布赋予不同的优先级

进程的三个状态

  • 就绪状态: 所有进程创建时都会进入就绪状态, 准备被调度
  • 运行状态: 进程被调度后就会获得CPU执行, 成为运行状态
  • 阻塞状态: 当进程遇到I/O操作时, 就会变为阻塞状态

同步和异步

  • 面向被调用者的消息通知机制

  • 同步: 被调用者得到结果再返回

  • 异步: 被调用方先返回, 再执行, 得到结果后再通知调用者

阻塞与非阻塞

  • 面向调用者的消息等待时的状态

  • 阻塞: 在调用结果返回前, 当前线程会被挂起等待, 知道拿到调用结果才会继续进行

  • 非阻塞: 在调用结果返回前, 可以继续进行其他操作

僵尸进程与孤儿进程

  • 僵尸进程: 指的是子进程已经结束, 但PID还在, 未被回收
  • 孤儿进程: 指的是子进程还在进行, 但父进程意外结束

守护进程

  • 指的是主进程结束后, 该主进程产生的所有子进程跟着结束并回收
from multiprocessing import Process
from multiprocessing import current_process
import time


def task(name):
    print(f'{name} started...', current_process().pid)
    time.sleep(1)
    print(f'{name} stopped...', current_process().pid)


if __name__ == '__main__':
    p = Process(target=task, args=('bigb',))
    p.daemon = True
    p.start()
    print('主进程')
    
# 主进程

Python中的进程操作

Process创建进程

from multiprocessing import Process
import time


def task(name):
    print(f'{name}的任务开始执行!')
    time.sleep(1)
    print(f'{name}的任务已经结束!')

# 创建子进程时, 子进程会加载并执行父进程代码
if __name__ == '__main__':
    # targent=执行函数的地址, args是该函数需要传入的参数
    p = Process(target=task, args=('bigb',))
    # 启动进程,并调用子进程中的p.run()
    p.start()
    print('主进程')

    
    
'''
主进程
bigb的任务开始执行!
bigb的任务已经结束!

'''
from multiprocessing import Process
import time


class MyProcess(Process):
    def run(self):
        print('子进程任务开始执行!')
        time.sleep(1)
        print('子进程任务已经结束!')


if __name__ == '__main__':
    p = MyProcess()
    # 启动进程,并调用子进程中的p.run()
    p.start()
    print('主进程')
    
'''
主进程
子进程任务开始执行!
子进程任务已经结束!
'''

  • p.join()主进程等待子进程终止
from multiprocessing import Process
import time


def task(name):
    print(f'{name}的任务开始执行!')
    time.sleep(1)
    print(f'{name}的任务已经结束!')


if __name__ == '__main__':
    p = Process(target=task, args=('bigb',))
    p.start()
    p.join()
    print('主进程')
    
'''
bigb的任务开始执行!
bigb的任务已经结束!
主进程
'''

  • current_process().pid 获取子进程pid
  • os.getpid 获取主进程pid
  • tasklist | findstr pid cmd中查看pid属于哪个进程
  • p.is_alive() 判断p进程是否存活
  • p.terminate() 终止p进程

进程间数据相互隔离

from multiprocessing import Process

x = 1


def foo():
    global x
    x = 2


if __name__ == '__main__':
    p = Process(target=foo)
    p.start()
    print(x)  # 1

推荐阅读