Python学习_22 Python多进程和多线程
1、进程概念
进程是程序在计算机上的一次执行活动,是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
进程的概念有两点:第一,进程是实体,每一个进程都有它自己的地址空间;第二,进程是一个“执行中的程序”
用户进程是指右普通用户启动的进程,是代码进程,进程是操作系统进行资源分配的单位
多进程:
在操作系统的管理下,所有正在运行的进程轮流使用CPU,每个进程允许占用CPU的时间非常短(比如10毫秒),这样用户感觉不出来CPU是在轮流为多个进程服务,就好像所有进程都在不间断的运行一样,但实际上在任何一个时间内有且仅有一个进程占有CPU
2、线程概念
线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
多线程:
线程是程序中一个单一的顺序控制流程。进程内有一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指令运行时的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。
3、多进程和多线程的区别
多进程使用的是CPU的多个核,适合运算密集型
多线程使用的是CPU一个核,适合IO密集型
4、Python组件multiprocessing
python提供了非常好用的多进程包,multiprocessing,只需导入该模块就可以用,他支持子进程、通信、共享数据,执行不同形式的同步,提供了Process、Pipe、Lock等组件
multiprocessing用到的两个方法:
cpu_count() 统计CPU总数
active_children() 获得所有子进程
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018\5\20 0020 0:37
# @Author : xiexiaolong
# @File : demon.py
import multiprocessing
import time
def worker(args, interval):
print("start worker {0}".format(args))
time.sleep(interval)
print("end worker {0}".format(args))
def main():
print("start main")
p1 = multiprocessing.Process(target=worker, args=(1, 1))
p2 = multiprocessing.Process(target=worker, args=(2, 2))
p3 = multiprocessing.Process(target=worker, args=(3, 3))
p1.start()
p2.start()
p3.start()
print("The number of CPU is :{0}".format(multiprocessing.cpu_count()))
for p in multiprocessing.active_children():
print("The name of active children is {0},pid i :{1}".format(p.name,p.pid))
print("end main")
if __name__ == '__main__':
main()
结果:
D:\python\venv\Scripts\python.exe D:/python/0519/demon.py
start main
The number of CPU is :4
The name of active children is Process-3,pid i :7748
The name of active children is Process-2,pid i :800
The name of active children is Process-1,pid i :6112
end main
start worker 2
start worker 1
start worker 3
end worker 1
end worker 2
end worker 3
Process finished with exit code 0
5、process类
Process 类用来描述一个进程对象。创建子进程的时候,只需要传入一个执行函数和函数的参数即可完成 Process 示例的创建。
创建一个process对象
p = process(target=workker_1,args=(2,))
target :函数名称
args:函数需要的参数,以tuple的形式传入
注意:单个元素的tuple的表现形式:(1,),有个,号
p代表一个多进程
p.is_alive() 判断进程是否存活
p.run() 启动进程
p.start() 启动进程,会自动调run()方法,推荐使用start
p.join(timeout) 等待子进程结束或者到超时时间直接下一步
p.terminate() 强制子进程退出
p.name 进程的名字
p.pip 进程的pid
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018\5\20 0020 0:37
# @Author : xiexiaolong
# @File : demon.py
import multiprocessing
import time
def worker(args, interval):
print("start worker {0}".format(args))
time.sleep(interval)
print("end worker {0}".format(args))
def main():
print("start main")
p1 = multiprocessing.Process(target=worker, args=(1, 1))
p2 = multiprocessing.Process(target=worker, args=(2, 2))
p3 = multiprocessing.Process(target=worker, args=(3, 3))
p1.start()
p2.start()
p3.start()
print("end main")
if __name__ == '__main__':
main()
结果:
D:\python\venv\Scripts\python.exe D:/python/0519/demon.py
start main
end main
start worker 2
start worker 3
start worker 1
end worker 1
end worker 2
end worker 3
Process finished with exit code 0
分析:
1、先执行主函数,直接打印开始
2、在连续多进程启动p1,p2,p3
3、由于p1,p2,p3有sleep,所以结束比较晚,这样结果看到主函数开始结束,然后依次结束p1,p2,p3
6、Lock组件
当我们用多进程来读写文件的时候,如果一个进程是写文件,一个进程是读文件,如果两个文件同时进行数据会不准确,必须是写文件结束以后才可以读文件操作,或者多个进程共享一些资源的时候,同时只能有一个进程进行访问,那就要用到锁机制
Lock对象有2中状态 loked和unlocked
使用方法acquire()设置为locked状态;
使用release()设置为unlocked状态。
例子:
不加锁;
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018\5\20 0020 1:20
# @Author : xiexiaolong
# @File : demon2.py
import multiprocessing
import time
def add(number, add_value):
try:
print("init add{0} number = {1}".format(add_value, number.value))
for i in range(1, 6):
number.value += add_value
print("***************add{0} has added***********".format(add_value))
time.sleep(1)
print("add{0} number = {1}".format(add_value, number.value))
except Exception as e:
raise e
if __name__ == "__main__":
number = multiprocessing.Value('i', 0)
p1 = multiprocessing.Process(target=add, args=(number, 1))
p2 = multiprocessing.Process(target=add, args=(number, 3))
p1.start()
p2.start()
print("main end")
结果:
D:\python\venv\Scripts\python.exe D:/python/0519/demon2.py
main end
init add1 number = 0
***************add1 has added***********
init add3 number = 1
***************add3 has added***********
add1 number = 4
***************add1 has added***********
add3 number = 5
***************add3 has added***********
add1 number = 8
***************add1 has added***********
add3 number = 9
***************add3 has added***********
add1 number = 12
***************add1 has added***********
add3 number = 13
***************add3 has added***********
add1 number = 16
***************add1 has added***********
add3 number = 17
***************add3 has added***********
add1 number = 20
add3 number = 20
Process finished with exit code 0
枷锁:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018\5\20 0020 0:37
# @Author : xiexiaolong
# @File : demon.py
import time
import multiprocessing
def add1(lock, value, number):
with lock:
print("start add1 number= {0}".format(number))
for i in range(1, 5):
number += value
time.sleep(0.3)
print("number = {0}".format(number))
def add3(lock, value, number):
lock.acquire()
print("start add3 number= {0}".format(number))
try:
for i in range(1, 5):
number += value
time.sleep(0.3)
print("number = {0}".format(number))
except Exception as e:
raise e
finally:
lock.release()
pass
if __name__ == '__main__':
print("start main")
number = 0
lock = multiprocessing.Lock()
p1 = multiprocessing.Process(target=add1, args=(lock, 1, number))
p3 = multiprocessing.Process(target=add3, args=(lock, 3, number))
p1.start()
p3.start()
print("end main")
结果:
D:\python\venv\Scripts\python.exe D:/python/0519/demon.py
start main
end main
start add1 number= 0
number = 1
number = 2
number = 3
number = 4
start add3 number= 0
number = 3
number = 6
number = 9
number = 12
Process finished with exit code 0
分析:add1函数直接带锁;add3获取锁,获取到之后才执行;
7、共享内存
python的multiprocessing模块也提供的共享内存的操作
一般的变量在进程之间是没法进行通讯的,multiprocessing 给我们提供了 Value 和 Array 模块,他们可以在不通的进程中共同使用
本文介绍了Python中多进程和多线程的基础概念、区别及应用实例,包括进程和线程的定义、多进程与多线程的特点、Python的multiprocessing模块使用方法等。

被折叠的 条评论
为什么被折叠?



