并发编程——多进程 随笔 第1张
from multiprocessing import Process
import time

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

    #必须写run方法
    def run(self):
        print('%s is running'%self.name)
        time.sleep(3)
        print('%s is over'%self.name)

if __name__ == '__main__':
    obj = MyProcess('egon')
    obj.start()
    print('主')

方式2 1、什么是进程?
      程序:堆代码
      进程:正在运行的程序
      进程是一个实体,每个进程都自己的独立内存空间

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

进程的三个状态:

并发编程——多进程 随笔 第3张

multiprocessing模块介绍

 

2、同步和异步:针对的程序运行的状态
      同步:提交任务后原地等待任务返回结果,期间不做任何事情
      异步:提交任务后,不等待任务返回结果,直接运行下一行代码
3、阻塞和非阻塞:针对程序运行的状态
     阻塞:遇到 IO 操作》》》阻塞状态
     非阻塞:就绪或者运行状态 >>>>就绪状态

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

强调:
1. 需要使用关键字的方式来指定参数
2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号
参数介绍:
1 group参数未使用,值始终为None
2
3 target表示调用对象,即子进程要执行的任务
4
5 args表示调用对象的位置参数元组,args=(1,2,'egon',)
6
7 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
8
9 name为子进程的名称
方法介绍:
1 p.start():启动进程,并调用该子进程中的p.run()
 2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法
 3
 4 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
 5 p.is_alive():如果p仍然运行,返回True
 6
 7 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程

4、开启进程的两种方式:
并发编程——多进程 随笔 第4张
form multiprocessing import Pocess
import time

def task(name)
	print('%s is running '%name)
	time.sleep(3)
	print('%s is over' %name)

if __name__ == '__main__':
	p1=Process(target=task,args=())
	p1.strat()
	print('主程序')
方式1 并发编程——多进程 随笔 第6张
from multiprocessing import Process
import time


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

    #必须写run方法
    def run(self):
        print('%s is running'%self.name)
        time.sleep(3)
        print('%s is over'%self.name)

if __name__ == '__main__':
    obj = MyProcess('egon')
    obj.start()
    print('主')
方式2

5、进程对象的join方法:

# join的作用仅仅只是让主进程等待子进程的结束,不会影响子进程的运行
并发编程——多进程 随笔 第8张
from multiprocessing import Process
import time


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


if __name__ == '__main__':
    start_time = time.time()
    p_list = []
    for i in range(3):
        p = Process(target=task,args=('子进程%s'%i,i))
        p.start()
        p_list.append(p)
    for i in p_list:
        i.join()

    print('主',time.time()-start_time)
join

6、进程之间空间独立

并发编程——多进程 随笔 第10张
from multiprocessing import Process

x = 100


def task():
    global x
    x = 1
    print(x)


if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    p.join()
    print('主', x)

'''
F:\python36\python3.exe F:/python_s7/week08/day02/进程间数据是隔离的.py
1
主 100
'''
空间独立

7、进程对象其他相关方法

并发编程——多进程 随笔 第12张
from multiprocessing import Process,current_process
import time
import os

def task():
    print('%s is running'%os.getpid())
    time.sleep(3)
    print('%s is over'%os.getppid())

if __name__ == '__main__':
    p1 = Process(target=task)
    p1.start()
    # p1.terminate()# 杀死子程序
    time.sleep(3)
    print(p1.is_alive())#判断子程序
    print('主')
其他方法

8、守护进程

主进程创建守护进程

  其一:守护进程会在主进程代码执行结束后就终止

  其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children

并发编程——多进程 随笔 第14张
from multiprocessing import Process
import time

def task(name):
    print('%s 正活着'%name)
    time.sleep(3)
    print('%s 正常死亡'%name)


if __name__ == '__main__':
    p = Process(target=task,args=('egon总管',))
    p.daemon = True  # 必须在p.start开启进程命令之前声明
    p.start()
    print('皇帝jason正在死亡')

join

9、互斥锁:

牺牲了效率但是保证了数据的安全


锁一定要在主进程中创建,给子进程去用
解决多个进程操作同一份数据,造成数据不安全的情况
加锁会将并发变成串行
锁通常用在对数据操作的部分,并不是对进程全程加锁

mutex.acquire()  # 抢锁   一把锁不能同时被多个人使用,没有抢到的人,就一直等待锁释放
buy(i)
mutex.release()  # 释放锁

并发编程——多进程 随笔 第16张
import json
import time
import random
from multiprocessing import Process, Lock


# 查票
def search(i):
    with open('info', 'r', encoding='utf-8')as f:
        data = json.load(f)
    print('用户查询余票%s' % data.get('ticket'))


def buy(i):
    # 购买前想查询余票
    with open('info', 'r', encoding='utf-8') as f:
        data = json.load(f)
    # 模拟延迟
    time.sleep(random.randint(1, 3))

    if data.get('ticket') > 0:
        data['ticket'] -= 1
        with open('info', 'w', encoding='utf-8')as f:
            json.dump(data, f)
        print('用户抢票成功%s' % i)
    else:
        print('用户%s抢票失败' % i)


def run(i, mutex):
    search(i)
    mutex.acquire()
    buy(i)
    mutex.release()


if __name__ == '__main__':
    mutex = Lock()
    for i in range(10):
        p = Process(target=run, args=(i, mutex))
        p.start()
互斥锁

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄