• 进程的实现以及常用方法


    进程的简介

    进程的本质也是程序,而且是正在运行的程序

    进程在运行过程中有三种状态,分别是就绪态、运行态以及阻塞态

    进程可以分为四种,分别为同步阻塞、同步非阻塞、异步阻塞以及异步非阻塞。

    同步是指一个任务的运行需要等待上一个任务的结束;异步是指将一个任务交给操作系统后继续去干其它的事,当该任务结束运行得到结果时只需告知一声即可。

    阻塞是指等待其它任务结束或者在原地等待结果;非阻塞是指无序等待,当得到结果后通知一下即可。

    在程序运行中,异步非阻塞效率最高。

    一、进程的实现方法

    1、直接调用Process模块

    import time
    from multiprocessing import Process
    
    
    # 第一种:调用Process模块
    def func(name):
        print("%s 启动了"%name)
        time.sleep(0.2)
        print("%s 结束了"%name)
    
    
    if __name__ == '__main__':
        p = Process(target=func,args=("egon",))
        p.start()
        print("")

    2、写一个类继承Process,调用内中的run方法

    import time
    from multiprocessing import Process
    
    
    # 第二种:继承Process模块,调用内中的run方法
    class MyProcess(Process):
        def __init__(self, name):
            super().__init__()
            self.name = name
    
        def run(self):
            print("%s 启动了" % self.name)
            time.sleep(0.2)
            print("%s 结束了" % self.name)
    
    
    if __name__ == '__main__':
        p = MyProcess("egon")
        p.start()
        print("")

    二、join方法

    子进程是由父进程开启的,父进程告诉操作系统创建一个子进程后就继续运行父进程的代码,父进程的代码可能会先运行完然后等待
    子进程运行结束,为了保证每个子进程运行完后父进程再运行结束,可以在告知操作系统创建子进程之后调用join方法,保证创建每个子进程后
    等待每个子进程的结束再运行并结束父进程。

    同时开启了多个子进程的时候,可以每开启一个子进程的时候将其添加到一个列表中,添加完毕后再通过另一个for循环
    将每个子进程取出,调用join方法。

    join方法要等每个所有子进程都被告知给操作系统之后使用。

    import time
    from multiprocessing import Process
    
    def func(i):
        print("%s 启动了"%i)
        time.sleep(i)
        print("%s 结束了"%i)
    
    lis = []
    if __name__ == '__main__':
        for i in range(10):
            p = Process(target=func,args=(i,))
            p.start()
            lis.append(p)
        for p in lis:
            p.join()
        print("")

    三、每个进程中的数据

    每一个进程间的数据是不能直接共用的,每个进程的数据都是独立的。
    即使时子进程和父进程的数据也是相互独立的。
    原因:每个进程再运行的时候,操作系统会给每个进程再内存中分配一块内存空间,也就导致了每个进程中的数据时相互独立的。

    from multiprocessing import Process
    import time
    
    
    money = 100
    
    def test():
        global money
        money = 99999999
    
    
    if __name__ == '__main__':
        p = Process(target=test)
        p.start()
        p.join()
        print(money)

    四、进程相关的方法

    current_process().pid:当前进程的PID
    getpid():获取当前进程的PID
    getppid():获取当前进程的父进程的PID
    import time
    import os
    from multiprocessing import Process
    
    def fun(name):
        print("%s 开始运行!"%name, os.getpid(),os.getppid())  # 第一个是子进程的端口号,第二个是父进程的端口号,实际上是每个进程所在的python解释器的端口号
        time.sleep(0.2)
        print("%s 结束运行!"%name, os.getpid(),os.getppid())
    
    
    if __name__ == '__main__':
        p = Process(target=fun,args=("egon",))
        p.start()
        print("",os.getpid(),os.getppid())  # 第一个是运行父进程的python解释器的端口号,第二个是运行解释器的pycharm编辑器的端口号

    五、守护进程

    守护进程顾名思义是为了保护某个进程的运行而被创建的。
    当被保护的进程死亡时,守护进程也会随之死亡。
    守护进程的设定应该在告诉操作系统创建该进程之前。

    import time
    from multiprocessing import Process
    
    
    def func(name):
        print("%s 正在运行" % name)
        time.sleep(0.2)
        print("%s 陪葬" % name)
    
    
    
    if __name__ == '__main__':
        p = Process(target=func,args=("egon",))
        p.daemon = True
        p.start()
        time.sleep(0.2)
        print("jason驾崩了!")
        time.sleep(1)

    六、守护进程

    当多个进程去访问同一个数据的时候,可以同时被多个进程拿到。
    当每个进程对拿到的数据进行修改操作并保存到原来的位置的时候,一般情况下每个进程都会认为是自己对该数据做了操作。
    但实际上每个进程的处理结果都会被下一个进程的处理结果覆盖,导致每个进程得到的反馈是都不正确。
    此时需要一个机制,对每个进程处理数据的操作进行限制,在同一时间只有一个进程对该数据进行操作,等待上一个进程处理完后下一个进程才能对数据进行处理。
    该机制就是互斥锁,给需要的数据在处理阶段进行上锁操作,每个进程需要拿到钥匙才能对数据进行操作,操作完毕后释放钥匙,下一个进程拿到钥匙后进行数据处理的操作。


    PS:钥匙应该只提供一个

     1 import time
     2 from multiprocessing import Process,Lock
     3 import json
     4 
     5 
     6 def search(i):
     7     with open("data.txt","r",encoding="utf-8") as f:
     8         data = f.read()
     9     dic = json.loads(data)
    10     num = dic.get("ticket")
    11     print("%s查询:还剩%s张票"%(i,num))
    12 
    13 def buy(i):
    14     with open("data.txt","r",encoding="utf-8") as f:
    15         data = f.read()
    16     dic = json.loads(data)
    17     num = dic.get("ticket")
    18     time.sleep(0.2)  # 模拟网络延迟
    19     if num == 0:
    20         print("没票了")
    21         return
    22     num -= 1
    23     dic["ticket"] = num
    24     with open("data.txt","w",encoding="utf-8") as a:
    25         json.dump(dic,a)
    26     print("%s抢票成功"%i)
    27 
    28 def run(*args):
    29     i,l = args
    30     search(i)
    31     l.acquire()
    32     buy(i)
    33     l.release()
    34 
    35 if __name__ == '__main__':
    36     l = Lock()
    37     for i in range(10):
    38         p = Process(target=run,args=(i,l),)
    39         p.start()
    40     print("zhu")
    41 
    42 """
    43 0查询:还剩1张票
    44 1查询:还剩1张票
    45 2查询:还剩1张票
    46 3查询:还剩1张票
    47 4查询:还剩1张票
    48 5查询:还剩1张票
    49 7查询:还剩1张票
    50 6查询:还剩1张票
    51 8查询:还剩1张票
    52 9查询:还剩1张票
    53 0抢票成功
    54 没票了
    55 没票了
    56 没票了
    57 没票了
    58 没票了
    59 没票了
    60 没票了
    61 没票了
    62 没票了
    63 """
    加了互斥锁
     1 import time
     2 from multiprocessing import Process,Lock
     3 import json
     4 
     5 
     6 def search(i):
     7     with open("data.txt","r",encoding="utf-8") as f:
     8         data = f.read()
     9     dic = json.loads(data)
    10     num = dic.get("ticket")
    11     print("%s查询:还剩%s张票"%(i,num))
    12 
    13 def buy(i):
    14     with open("data.txt","r",encoding="utf-8") as f:
    15         data = f.read()
    16     dic = json.loads(data)
    17     num = dic.get("ticket")
    18     time.sleep(0.2)  # 模拟网络延迟
    19     if num == 0:
    20         print("没票了")
    21         return
    22     num -= 1
    23     dic["ticket"] = num
    24     with open("data.txt","w",encoding="utf-8") as a:
    25         json.dump(dic,a)
    26     print("%s抢票成功"%i)
    27 
    28 def run(*args):
    29     i,l = args
    30     search(i)
    31     # l.acquire()
    32     buy(i)
    33     # l.release()
    34 
    35 if __name__ == '__main__':
    36     l = Lock()
    37     for i in range(10):
    38         p = Process(target=run,args=(i,l),)
    39         p.start()
    40     print("zhu")
    41 """
    42 0查询:还剩1张票
    43 1查询:还剩1张票
    44 3查询:还剩1张票
    45 2查询:还剩1张票
    46 4查询:还剩1张票
    47 5查询:还剩1张票
    48 6查询:还剩1张票
    49 7查询:还剩1张票
    50 8查询:还剩1张票
    51 9查询:还剩1张票
    52 0抢票成功
    53 1抢票成功
    54 3抢票成功
    55 2抢票成功
    56 4抢票成功
    57 5抢票成功
    58 6抢票成功
    59 7抢票成功
    60 8抢票成功
    61 9抢票成功
    62 """
    没加锁
  • 相关阅读:
    linux下查看jdk路径
    mysql内部级联删除
    Mybatis Mapper.java和Mapper.xml能否分离问题
    The request sent by the client was syntactically incorrect问题解决
    centos下-MariaDB的安装
    对于mariadb安装后可以默认使用无密码登录的问题解决方案
    C#复习笔记(2)--C#1所搭建的核心基础
    C#精粹--协变和逆变
    linux和sqlserver 2017的安装
    C#精粹--闭包陷阱
  • 原文地址:https://www.cnblogs.com/le-le666/p/11329282.html
Copyright © 2020-2023  润新知