1.多进程

        1.1 进程

程序:xxx.py是程序,是静态的

进程:一个程序运行起来后,代码+用到的资源 称之为进程,它是操作系统分配资源的基本单元。不仅可以通过线程完成多任务,进程也可以

        1.2进程的状态

python 类中开启多进程 python 类 多进程_python 类中开启多进程

 2.进程的创建-multiprocessing

        1.Process类语法

 

python 类中开启多进程 python 类 多进程_python 类中开启多进程_02

multiprocessing.Process对象具有如下方法和属性 :

python 类中开启多进程 python 类 多进程_servlet_03

        2. 2个while循环一起执行

# -*- coding:utf-8 -*-
from multiprocessing import Process
import time


def run_proc():
    """子进程要执行的代码"""
    while True:
        print("----2----")
        time.sleep(1)


if __name__=='__main__':
    p = Process(target=run_proc)
    p.start()
    while True:
        print("----1----")
        time.sleep(1)

python 类中开启多进程 python 类 多进程_python 类中开启多进程_04

 

python 类中开启多进程 python 类 多进程_jvm_05

         3.进程pid

# -*- coding:utf-8 -*-
from multiprocessing import Process
import os
import time

def run_proc():
    """子进程要执行的代码"""
    print('子进程运行中,pid=%d...' % os.getpid())  # os.getpid获取当前进程的进程号
    print('子进程将要结束...')

if __name__ == '__main__':
    print('父进程pid: %d' % os.getpid())  # os.getpid获取当前进程的进程号
    p = Process(target=run_proc)
    p.start()

 

python 类中开启多进程 python 类 多进程_子进程_06

        4.给子进程指定的函数传递参数 

# -*- coding:utf-8 -*-
from multiprocessing import Process
import os
from time import sleep


def run_proc(name, age, **kwargs):
    for i in range(10):
        print('子进程运行中,name= %s,age=%d ,pid=%d...' % (name, age, os.getpid()))
        print(kwargs)
        sleep(0.2)

if __name__=='__main__':
    p = Process(target=run_proc, args=('test',18), kwargs={"m":20})
    p.start()
    sleep(1)  # 1秒中之后,立即结束子进程
    p.terminate()
    p.join()

python 类中开启多进程 python 类 多进程_jvm_07

         5.进程间不同享全局变量

# -*- coding:utf-8 -*-
from multiprocessing import Process
import os
import time

nums = [11, 22]

def work1():
    """子进程要执行的代码"""
    print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
    for i in range(3):
        nums.append(i)
        time.sleep(1)
        print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))

def work2():
    """子进程要执行的代码"""
    print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))

if __name__ == '__main__':
    p1 = Process(target=work1)
    p1.start()
    p1.join()

    p2 = Process(target=work2)
    p2.start()

python 类中开启多进程 python 类 多进程_java_08

 3.进程间同步-Queue

        

python 类中开启多进程 python 类 多进程_java_09

        1.Queue类语法 

python 类中开启多进程 python 类 多进程_子进程_10

        2.Queue的使用 

python 类中开启多进程 python 类 多进程_python 类中开启多进程_11

 

#coding=utf-8
from multiprocessing import Queue
q=Queue(3) #初始化一个Queue对象,最多可接收三条put消息
q.put("消息1") 
q.put("消息2")
print(q.full())  #False
q.put("消息3")
print(q.full()) #True

#因为消息列队已满下面的try都会抛出异常,第一个try会等待2秒后再抛出异常,第二个Try会立刻抛出异常
try:
    q.put("消息4",True,2)
except:
    print("消息列队已满,现有消息数量:%s"%q.qsize())

try:
    q.put_nowait("消息4")
except:
    print("消息列队已满,现有消息数量:%s"%q.qsize())

#推荐的方式,先判断消息列队是否已满,再写入
if not q.full():
    q.put_nowait("消息4")

#读取消息时,先判断消息列队是否为空,再读取
if not q.empty():
    for i in range(q.qsize()):
        print(q.get_nowait())

python 类中开启多进程 python 类 多进程_servlet_12

        3.Queue实例 

python 类中开启多进程 python 类 多进程_jvm_13

 

from multiprocessing import Process, Queue
import os, time, random

# 写数据进程执行的代码:
def write(q):
    for value in ['A', 'B', 'C']:
        print('Put %s to queue...' % value)
        q.put(value)
        time.sleep(random.random())

# 读数据进程执行的代码:
def read(q):
    while True:
        if not q.empty():
            value = q.get(True)
            print('Get %s from queue.' % value)
            time.sleep(random.random())
        else:
            break

if __name__=='__main__':
    # 父进程创建Queue,并传给各个子进程:
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    # 启动子进程pw,写入:
    pw.start()    
    # 等待pw结束:
    pw.join()
    # 启动子进程pr,读取:
    pr.start()
    pr.join()
    # pr进程里是死循环,无法等待其结束,只能强行终止:
    print('')
    print('所有数据都写入并且读完')

python 类中开启多进程 python 类 多进程_java_14

4.进程间同步-Lock 

python 类中开启多进程 python 类 多进程_子进程_15

         2.程序不加锁

import multiprocessing
import time


def add(num, value):
    print('add{0}:num={1}'.format(value, num))
    for i in range(0, 2):
        num += value
        print('add{0}:num={1}'.format(value, num))
        time.sleep(1)


if __name__ == '__main__':
    lock = multiprocessing.Lock()
    num = 0
    p1 = multiprocessing.Process(target=add, args=(num, 1))
    p2 = multiprocessing.Process(target=add, args=(num, 2))
    p1.start()
    p2.start()

运行结果:运行无顺序,进程交替进行

python 类中开启多进程 python 类 多进程_python 类中开启多进程_16

         3.程序加锁

import multiprocessing
import time


def add(num, value, lock):
    try:
        lock.acquire()
        print('add{0}:num={1}'.format(value, num))
        for i in range(0, 2):
            num += value
            print('add{0}:num={1}'.format(value, num))
            time.sleep(1)
    except Exception as err:
        raise err
    finally:
        lock.release()


if __name__ == '__main__':
    lock = multiprocessing.Lock()
    num = 0
    p1 = multiprocessing.Process(target=add, args=(num, 1, lock))
    p2 = multiprocessing.Process(target=add, args=(num, 2, lock))
    p1.start()
    p2.start()

运行结果:只有其中一个进程执行完成后,其它进程才会执行,且谁先抢到,谁先执行

python 类中开启多进程 python 类 多进程_python 类中开启多进程_17

5.进程池Pool 

     1.Pool类语法

python 类中开启多进程 python 类 多进程_java_18

 multiprocessing.Pool常用函数:

python 类中开启多进程 python 类 多进程_子进程_19

         2.Pool实例

python 类中开启多进程 python 类 多进程_servlet_20

# -*- coding:utf-8 -*-
from multiprocessing import Pool
import os, time, random

def worker(msg):
    t_start = time.time()
    print("%s开始执行,进程号为%d" % (msg,os.getpid()))
    # random.random()随机生成0~1之间的浮点数
    time.sleep(random.random()*2) 
    t_stop = time.time()
    print(msg,"执行完毕,耗时%0.2f" % (t_stop-t_start))

po = Pool(3)  # 定义一个进程池,最大进程数3
for i in range(0,10):
    # Pool().apply_async(要调用的目标,(传递给目标的参数元祖,))
    # 每次循环将会用空闲出来的子进程去调用目标
    po.apply_async(worker,(i,))

print("----start----")
po.close()  # 关闭进程池,关闭后po不再接收新的请求
po.join()  # 等待po中所有子进程执行完成,必须放在close语句之后
print("-----end-----")

 

python 类中开启多进程 python 类 多进程_java_21

 

        3.进程池中的Queue

python 类中开启多进程 python 类 多进程_jvm_22

 

# -*- coding:utf-8 -*-

# 修改import中的Queue为Manager
from multiprocessing import Manager,Pool
import os,time,random

def reader(q):
    print("reader启动(%s),父进程为(%s)" % (os.getpid(), os.getppid()))
    for i in range(q.qsize()):
        print("reader从Queue获取到消息:%s" % q.get(True))

def writer(q):
    print("writer启动(%s),父进程为(%s)" % (os.getpid(), os.getppid()))
    for i in "itcast":
        q.put(i)

if __name__=="__main__":
    print("(%s) start" % os.getpid())
    q = Manager().Queue()  # 使用Manager中的Queue
    po = Pool()
    po.apply_async(writer, (q,))

    time.sleep(1)  # 先让上面的任务向Queue存入数据,然后再让下面的任务开始从中取数据

    po.apply_async(reader, (q,))
    po.close()
    po.join()
    print("(%s) End" % os.getpid())

python 类中开启多进程 python 类 多进程_java_23

6.进程,线程对比 

        1.功能

python 类中开启多进程 python 类 多进程_servlet_24

 

python 类中开启多进程 python 类 多进程_python 类中开启多进程_25

        2.区别 

python 类中开启多进程 python 类 多进程_子进程_26

        3.优缺点 

python 类中开启多进程 python 类 多进程_jvm_27