二十七、多进程,互斥锁

 

一、创建进程

创建进程就是在内存中重新开辟一块内存空间
将允许产生的代码丢进去
一个进程对应在内存就是一块独立的内存空间,和其他之间没有任何关系,变量也是独立的

进程与进程之间数据是隔离的 无法直接交互
但是可以通过某些技术实现间接交互
"""
如果调用函数,势必会同步等待时间结束完,才会执行其他代码,这里就是多进程同时执行,无需等待。 os.getpid() 显示进程数
os.getppid())  # 查询当前进程的父进程是谁
主程序和子程序在异步过程中,是随机运行的
两种方式:

 1.第一种:   

from multiprocessing import Process
import time
import os


def test(name):
    print('%s is running' % name, os.getpid())
    print('子进程父进程:', os.getppid())
    time.sleep(3)
    print('%s is over' % name, os.getpid())
    print('子进程父进程:', os.getppid())


"""
windows创建进程会将代码以模块的方式 从上往下执行一遍
linux会直接将代码完完整整的拷贝一份


windows创建进程一定要在if __name__ == '__main__':代码块内创建  否则报错
"""
if __name__ == '__main__':
    p = Process(target=test, args=('子进程:',))  # 注册 创建一个进程对象       p是一个进程对象
    p.start()  # 告诉操作系统帮你开启子进程,
    print('父进程:', os.getpid())  # 查询当前进程数字
    print('父进程父进程:', os.getppid())  # 查询当前进程的父进程是谁

2.第二方法:

import os
from multiprocessing import Process


class MyProcess(Process):
    def __init__(self, arg1, arg2):
        super().__init__() #初始化到父类,下面是派生属性
        self.arg1 = arg1
        self.arg2 = arg2

    def run(self):
        print(self.arg1,self.arg2)
        print(self.pid)  # 等同于os.getpid()
        print(self.name)
        print("子进程:", os.getpid())


if __name__ == '__main__':
    # print("主进程:", os.getpid())
    p1 = MyProcess(1,2)
    p1.start()
    p2 = MyProcess(3,4)
    p2.start()
    print("主进程:", os.getpid())

 

二、开启多个字进程,p.join()使用方法

join():

主进程代码等待子进程运行结束
p.join()上面是异步执行(子程序),下面是同步执行(主程序),没有p.join()都是异步
from multiprocessing import Process
import time
def test(name, i): print('%s is running' % name) time.sleep(i) print('%s is over' % name) if __name__ == '__main__': p_list = [] for i in range(3): p = Process(target=test,args=('进程%s'%i,i)) p.start() p_list.append(p) [p.join() for p in p_list]
   # start_time =time.time()
# p = Process(target=test, args=('egon', 1)) # p1 = Process(target=test, args=('kevin', 2)) # p2 = Process(target=test, args=('jason', 3)) # p.start() # 仅仅是告诉操作系统帮你创建一个进程 至于这个进程什么时候创 操作系统随机决定 # p1.start() # p2.start() # p2.join() # p.join() # p1.join() # 主进程代码等待子进程运行结束 才继续运行 # p.join() # 主进程代码等待子进程运行结束 print('') print(time.time() - start_time)

三、进程与进程之间隔离

  进程与进程之间是相互隔离,都是独立的一块内存空间,数据不共享
from multiprocessing import Process

money = 100


def test():
    global money
    money = 99999999


if __name__ == '__main__':
    p = Process(target=test)
    p.start()
    p.join()
    print(money) #100

 

 四、守护进程

把子进程改为守护进程,在start()上面添加p.daemon,子进程会随着主进程的结束而结束
def test(name):
    while True:
        print('%s总管正常活着' % name)
        time.sleep(3)
        print('%s总管正常死亡' % name)


if __name__ == '__main__':
    p = Process(target=test, args=('egon',))
    p.daemon = True  # 将该进程设置为守护进程   这一句话必须放在start语句之前 否则报错
    p.start()
    i = 0
    while i < 10:
        time.sleep(0.1)
        print('皇帝jason寿正终寝')
        i += 1

# 随着主进程的结束而结束

五、互斥锁

from multiprocessing import Process, Lock
import time
import json


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


# 买票
def buy(i):
    with open('data', 'r', encoding='utf-8') as f:
        data = f.read()
    t_d = json.loads(data)
    time.sleep(1)
    if t_d.get('ticket') > 0:
        # 票数减一
        t_d['ticket'] -= 1
        # 更新票数
        with open('data', 'w', encoding='utf-8') as f:
            json.dump(t_d, f)
        print('用户%s抢票成功' % i)
    else:
        print('没票了')


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()

 六、死锁(递归锁)

死锁:同一段代码,如果出现两把或两把以上锁就会出现 死锁 (多进程和多线程都会出现)
from threading import Lock, Thread
import time

noodle_lock = Lock()
fork_lock = Lock()


def eat1(name):
    noodle_lock.acquire()
    print("%s拿到面条啦!" % name)
    fork_lock.acquire()
    print("%s拿到叉子了" % name)
    print("%s可以吃面楼!" % name)
    fork_lock.release()
    noodle_lock.release()


def eat2(name):
    fork_lock.acquire()
    print("%s拿到叉子了2" % name)
    time.sleep(1)
    noodle_lock.acquire()
    print("%s拿到面条啦2!" % name)
    print("%s可以吃面楼2!" % name)
    noodle_lock.release()
    fork_lock.release()


Thread(target=eat1, args=("alex",)).start()
Thread(target=eat2, args=("json",)).start()
Thread(target=eat1, args=("tank",)).start()
Thread(target=eat2, args=("jirry",)).start()
# 锁是共通的,两个函数锁相互抢(如果没有阻塞就没问题)
死锁
递归锁:Rlock 是一串钥匙,拿到了就可以路通到底
# 锁是唯一的,全局变量

#递归锁:Rlock 是一串钥匙,拿到了就可以路通到底
from threading import RLock, Thread

import time

fork_lock=noodle_lock = RLock()  # RLOCK递归锁,一个钥匙串上两把钥匙

def eat1(name):
    noodle_lock.acquire()
    print("%s拿到面条啦!" % name)
    fork_lock.acquire()
    print("%s拿到叉子了" % name)
    print("%s可以吃面楼!" % name)
    fork_lock.release()
    noodle_lock.release()


def eat2(name):
    fork_lock.acquire()
    print("%s拿到叉子了" % name)
    time.sleep(1)
    noodle_lock.acquire()
    print("%s拿到面条啦!" % name)
    print("%s可以吃面楼!" % name)
    noodle_lock.release()
    fork_lock.release()


Thread(target=eat1, args=("alex",)).start()
Thread(target=eat2, args=("json",)).start()
Thread(target=eat1, args=("tank",)).start()
Thread(target=eat2, args=("jirry",)).start()

 

posted @ 2019-08-09 23:17  凯帅  阅读(258)  评论(0编辑  收藏  举报