zoukankan      html  css  js  c++  java
  • 二十七、多进程,互斥锁

    一、创建进程

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

    进程与进程之间数据是隔离的 无法直接交互
    但是可以通过某些技术实现间接交互
    """
    如果调用函数,势必会同步等待时间结束完,才会执行其他代码,这里就是多进程同时执行,无需等待。 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()
  • 相关阅读:
    ntohs, ntohl, htons,htonl的比较和详解【转】
    Device Tree 详解【转】
    浅析Linux DeviceTree【转】
    【spring boot】spring boot 拦截器
    【jQuery】jQuery/js 判断字符串是否JSON字符串
    【java】java中的 &= 和 |= 和 ^= 的区别
    zabbix创建触发器、action,发送报警邮件
    html iframe禁用右键
    mysql数据库mysqldump方式备份
    JDK8新特性
  • 原文地址:https://www.cnblogs.com/wukai66/p/11330057.html
Copyright © 2011-2022 走看看