zoukankan      html  css  js  c++  java
  • 多进程

    多道技术:

      1.空间上的复用:多个应用程序可以共享同一套计算机硬件,程序的内存与内存之间是相互隔离的,是物理的上 隔离。

      2.时间上的复用:切换+保存状态

        1.在程序遇到IO操作的时候,便会被操作系统剥夺cpu权限,并保存状态

        2.就是一个程序长时间占用cpu便会被操作系统剥夺cpu权限,并保留状态。

      并发:多个任务同时发生,看着像同时进行,其实切换执行,只是切换的速度快

      并行:多个任务真正意义上的同时进行。(必须要多核)

    程序与进程的区别:
      程序就是指一堆代码。进程:指的是正在运行的程序。一个静态,一个动态。

    开启进程的2种方式

    1

    from multiprocessing import Process
    
    def task(name):
        print('%s is running' % name)
    
    
    if __name__ == '__main__':
        p = Process(target=task,args=('liuwei',))
        p.start()
        print('主进程 is running')
    View Code

    2继承Process自己手动改run方法:

    class MyProcess(Process):
        def __init__(self,name):
            super().__init__()
            self.name = name
    
        def run(self):
            print('%s is running' % self.name)
    
    if __name__ == '__main__':
        p = MyProcess('lw')
        p.start()
        print('')
    View Code

    同步异步:(任务的提交方式)

    同步:任务提交后,会等待任务的返回结果,期间不会执行其他任何操作

    异步:任务提交后,不会等待任务的返回结果,会继续执行下一行代码。(结果肯定要的,用的异步回调的机制)

    阻塞和非阻塞:(任务的运行状态)

    阻塞:程序遇到了IO操作那么就是阻塞

    非阻塞:程序没有遇到IO操作那么就是非阻塞

    程序的3种运行状态:

    就绪,运行,阻塞。

     僵尸进程与孤儿进程:

    所有的进程都会步入僵尸进程,就是因为进程结束后,没有完全回收完。

    父进程回收子进程资源的两种方式:

      1.join方法

      2.父进程正常死亡

    有危害的,会占用内存资源

    孤儿进程:

    父进程先于子进程结束,这个时候子进程会被操作系统所接管。有一定的存在的意义。

    进程的一些方法:

    join是提高子进程的优先级,会让子进程先执行。

    os.getpid 获取当前进程的进程号

    os.getppid 获取当前进程父进程的进程号

    is_alive 判断进程是否存活

    terminate 杀死当前进程

    name 获取进程的名字

    进程与进程之间是相互隔离的

    from multiprocessing import Process
    import time
    x=1000
    def task():
        global x
        x=0
        print('儿子死啦',x)
    
    
    if __name__ == '__main_
        print(x)
        p=Process(target=task)
        p.start()
        time.sleep(5)
        print(x)
    View Code

    守护进程:

    就是创建一个进程为守护进程,当被守护的进程结束后,那么守护进程也会立即结束,注意的是,守护进程一旦在被守护进程结束后,会立即结束,不会等其他的非守护进程。

    from multiprocessing import Process
    import time
    
    
    def test(name):
        print('%s总管正常活着'%name)
        time.sleep(3)
        print('%s总管正常死亡'%name)
    
    
    if __name__ == '__main__':
        p = Process(target=test,args=('egon',))
        p.daemon = True  # 将该进程设置为守护进程   这一句话必须放在start语句之前 否则报错
        p.start()
        time.sleep(0.1)
        print('皇帝jason寿正终寝')
    View Code

    互斥锁 Lock

    当多个进程同时操作同一个数据的时候,任意造成数据错乱。

    这个就需要加锁了,将并发变成串行,还不影响公平性,牺牲效率提升数据的安全性。

    一把枷锁对应一个解锁,不然会造成死锁。

    锁必须在主进程产生,交由子进程使用。

    加锁:mutex.acquire()

    解锁:mutex.release()

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

     

  • 相关阅读:
    MySQL存储引擎与索引
    最长公共子序列
    最长递增子序列
    排序算法
    二分查找及其变种
    多线程中锁的种类。
    <LeetCode>136. 只出现一次的数字
    <LeetCode>121. 买卖股票的最佳时机
    Netty 粘包/拆包应用案例及解决方案分析
    微服务
  • 原文地址:https://www.cnblogs.com/xinfan1/p/11328478.html
Copyright © 2011-2022 走看看