Python学习_22 Python多进程和多线程

本文介绍了Python中多进程和多线程的基础概念、区别及应用实例,包括进程和线程的定义、多进程与多线程的特点、Python的multiprocessing模块使用方法等。

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 模块,他们可以在不通的进程中共同使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值