三十三、进程理论

一、进程理论

1、程序和进程

程序:一堆代码

进程:正在运行的程序

进程是一个实体,每一个进程都有它自己独立的内存空间

2、同步和异步:针对任务的提交方式

同步:提交任务之后,原地等待任务的返回结果,期间不做任何事(叫人吃饭,一直等待)

异步:提交任务之后,不等待任务的返回结果,执行运行下一行代码(叫人吃饭,但自己先走) 

3、阻塞与非阻塞:针对程序运行的状态

阻塞:遇到io操作 ->>阻塞态

非阻塞:就绪或者运行态

 

二、创建进程的两种方式

1、方式一

from multiprocessing import Process
import time

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


# 注意,在windows系统中,创建进程会将代码以模块的方式从头到尾加载一遍
# 一定要写在if __name__ == '__main__':代码块里面
# 强调:函数名一旦加括号,执行优先级最高,立刻执行
if __name__ == '__main__':
    p1 = Process(target=task, args=('egon',))   # # 这一句话只是实例化了一个Process对象
    p1.start()     # 告诉操作系统创建一个进程
    print('主进程')

2、方式二

from multiprocessing import Process
import time

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

    def run(self):
        print('%s is running' % self.name)
        time.sleep(1)
        print('%s is end' % self.name)

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

三、join方法:join主进程等待子进程结束 才继续运行

from multiprocessing import Process
import time

def task(name, n):
    print('%s is running' % name)
    time.sleep(n)
    print('%s is end' % 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)

# 结果为
# 子进程0 is running
# 子进程0 is end
# 子进程1 is running
# 子进程2 is running
# 子进程1 is end
# 子进程2 is end
# 主进程 2.624150037765503


 

四、进程对象其他方法

# 了解
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(0.1)
    print(p1.is_alive())  # 判断子进程是否存活
    print('')

五、进程之间内存隔离

# 记住 进程与进程之间数据是隔离的!!!
from multiprocessing import Process

x = 100
def task():
    global x
    x = 20
    print('子进程', x)


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

# 结果为
# 子进程 20
# 主进程 100

六、守护进程

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()
    print('jason正在死亡')

# 结果为 jason正在死亡

 

七、互斥锁

互斥锁(***)
①锁千万不要随意去用
②牺牲了效率但是保证了数据的安全
③锁一定要在主进程中创建,给子进程去用
④解决多个进程操作同一份数据,造成数据不安全的情况
⑤加锁会将并发变成串行
⑥锁通常用在对数据操作的部分,并不是对进程全程加锁
mutex.acquire()  # 抢锁   一把锁不能同时被多个人使用,没有抢到的人,就一直等待锁释放
buy(i)
mutex.release()  # 释放锁
from multiprocessing import Process, Lock
import json
import time
import random

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查询余票为0' % i)

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

if __name__ == '__main__':
    mutex = Lock()       # 创建锁
    for i in range(5):
        p = Process(target=run, args=(i, mutex))
        p.start()

# 结果为
# 用户查询余票数3
# 用户查询余票数3
# 用户查询余票数3
# 用户查询余票数3
# 用户查询余票数3
# 用户1抢票成功
# 用户0抢票成功
# 用户2抢票成功
# 用户3查询余票为0
# 用户4查询余票为0

猜你喜欢

转载自www.cnblogs.com/zhangguosheng1121/p/10822825.html