进程的实现以及常用方法

  • Post author:
  • Post category:其他



进程的简介

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

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

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

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

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

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

一、进程的实现方法

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 """


没加锁

转载于:https://www.cnblogs.com/le-le666/p/11329282.html