设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 手机 数据
当前位置: 首页 > 服务器 > 系统 > 正文

并发编程-多进程

发布时间:2021-01-07 09:21 所属栏目:52 来源:网络整理
导读:一.进程 新进程的创建都是由一个 已经存在的进程 执行了一个 用于创建进程的系统调用 而创建的。 1.在UNIX中:fork会创建一个与父进程一摸一样的副本 2.在Windows:系统调用CreateProcess创建进程 进程的状态 程序遇到IO操作(Input、output),会阻塞,IO完成

一.进程

新进程的创建都是由一个已经存在的进程执行了一个用于创建进程的系统调用而创建的。

1.在UNIX中:fork会创建一个与父进程一摸一样的副本

2.在Windows:系统调用CreateProcess创建进程

进程的状态

程序遇到IO操作(Input、output),会阻塞,IO完成会进入就绪状态,此时等待cpu执行。正在执行的程序时间片完(cpu切到其他程序执行),会进入就绪状态。

并发编程-多进程

1.进程创建方式

在windows环境下,开启进程必须在 if __name__ == "__main__"下

并发编程-多进程

并发编程-多进程

from multiprocessing import Process
import time

def task(name):
    print(f"{name} is running")
    time.sleep(3)
    print(f"{name} is gone")

if __name__ == ‘__main__‘:
    p = Process(target=task,args=("alex",))  # 指定 这个线程去哪个函数里面去执行代码
    p.start()   #只是向操作系统发出一个开辟子进程的信号(由cpu执行进程中额任务),然后就执行下一行了
    print("__main__")


#操作系统在接受到信号之后,会在内存中开辟一个进程空间(新建一个子进程py文件),然后将主进程所有数据copy到子进程(相当于在子进程py文件中import主进程的所有内容,那么if __name__ == "__main__"下面的不会导过来),然后调用线程执行。
#开辟子进程的开销很大(时间很长),所以永远会执行主进程的代码。
进程创建的方式一

并发编程-多进程

并发编程-多进程

from multiprocessing import Process
import time
class MyProcess(Process):
    def run(self):
        print(f"{self.name} is running")
        time.sleep(3)
        print(f"{self.name} is end")

if __name__ == ‘__main__‘:
    p = MyProcess()
    p.start()              # 会自动执行run方法(run方法相当于上面的task函数)
    print("__main__")


#Process类中有name属性,默认为类名加上-1(MyProcess-1),每次新建一个子进程就MyProcess-2、MyProcess-3...
进程创建的方式二

二.进程pid

在pycharm中,父进程为pycharm,子进程为pycharm调用的python解释器。

并发编程-多进程

并发编程-多进程

import os
import time
print(f"子进程:{os.getpid()}")   #运行此py文件的python解释器的pid
print(f"父进程":{os.getppid()})  #当前pycharm的pid
pycharm查看进程id

并发编程-多进程

并发编程-多进程

from multiprocessing import Process
import time
import os

def task(name):
    print(f‘子进程:{os.getpid()}‘)
    print(f‘主进程:{os.getppid()}‘)

if __name__ == ‘__main__‘:
    p = Process(target=task,args=(‘常鑫‘,))  # 创建一个进程对象
    p.start()
    # print(‘==主开始‘)
    print(f‘====主{os.getpid()}‘)
示例代码

在cmd中,父进程为cmd,子进程为cmd调用的python解释器

并发编程-多进程

并发编程-多进程

#tasklist获取所有进程的pid
#tasklist | findstr pycharm 指定获取某一个进程
cmd查看进程id

三.进程之间的空间隔离

进程之间相互隔离,是不能互相修改数据的

并发编程-多进程

并发编程-多进程

from multiprocessing import Process
import time
name = ‘太白‘

def task():
    global name
    name = ‘刚子sb‘
    print(f‘子进程{name}‘)


if __name__ == ‘__main__‘:
    p = Process(target=task)  # 创建一个进程对象
    p.start()
    time.sleep(3)
    print(f‘主:{name}‘)


#打印结果
#子进程刚子sb
#主:太白
示例代码

四.join

join就是阻塞,只有join执行完,才会执行join下面的主进程代码

并发编程-多进程

并发编程-多进程

from multiprocessing import Process
import time
def task1(name):
    print(f"{name} is running")
    time.sleep(1)
    print(f"{name} is gone")

def task2(name):
    print(f"{name} is running")
    time.sleep(2)
    print(f"{name} is gone")

def task3(name):
    print(f"{name} is running")
    time.sleep(3)
    print(f"{name} is gone")

if __name__ == ‘__main__‘:
    start_time = time.time()
    p1 = Process(target=task1,args=("alex",))
    p2 = Process(target=task2,args=(‘egon‘,))
    p3 = Process(target=task3,args=(‘meet‘,))

    p1.start()
    p2.start()
    p3.start()

    p1.join()
    p2.join()
    p3.join()

    print(time.time() - start_time)

    
打印结果
alex is running
egon is running
meet is running
alex is gone
egon is gone
meet is gone
3.101801872253418

#我们看到,只执行了3s左右,因为p1.start(),p2.start(),p3.start()三个相当于并发执行,p1.join()执行的过程中p2,p3也会执行,其实就是并发。
示例1

并发编程-多进程

并发编程-多进程

from multiprocessing import Process
import time
def task1(name):
    print(f"{name} is running")
    time.sleep(1)
    print(f"{name} is gone")

def task2(name):
    print(f"{name} is running")
    time.sleep(2)
    print(f"{name} is gone")

def task3(name):
    print(f"{name} is running")
    time.sleep(3)
    print(f"{name} is gone")

if __name__ == ‘__main__‘:
    start_time = time.time()
    p1 = Process(target=task1,))

    p1.start()
    p2.start()
    p3.start()

    p1.join()
    print("p1")
    p2.join()
    print("p2")
    p3.join()
    print("p3")

    print(time.time() - start_time)

打印结果:
alex is running
egon is running
meet is running
alex is gone
p1                                    #1s执行打印p1
egon is gone
p2                                    #第2s执行打印p2,因为p2已经执行了1s
meet is gone
p3
3.1154708862304688
示例2

并发编程-多进程

并发编程-多进程

from multiprocessing import Process
import time,random

def task():
    print("task begin")
    time.sleep(random.randint(1,2))
    print("task end")

if __name__ == ‘__main__‘:
    start_time = time.time()
    for i in range(3):
        p = Process(target=task)
        p.start()
        p.join()                     

    print("__main__")
    print(time.time() - start_time)

# 上述例子为串行,每start()一次,就join一次,我们都知道,有join会等到join完成后再执行下面的代码。正确例子如下:

from multiprocessing import Process
import time,2))
    print("task end")

if __name__ == ‘__main__‘:
    start_time = time.time()
    lst = []
    for i in range(3):
        p = Process(target=task)
        lst.append(p)
        p.start()
    for j in lst:
        j.join()            

    print("__main__")
    print(time.time() - start_time)
经典示例

五.进程的其他参数

并发编程-多进程

from multiprocessing import Process
import time

def task(name):
    print(f‘{name} is running‘)
    time.sleep(2)
    print(f‘{name} is gone‘)



if __name__ == ‘__main__‘:
    # 在windows环境下,开启进程必须在 __name__ == ‘__main__‘ 下面
    # p = Process(target=task,args=(‘常鑫‘,))  # 创建一个进程对象
    p = Process(target=task,),name=‘alex‘)  # 创建一个进程对象
    p.start()
    time.sleep(1)
    p.terminate()  # 杀死子进程(可以理解为发送信号,需要时间)  ***
    p.join()  # ***
    time.sleep(0.5)
    print(p.is_alive())   # 查看进程是否存活***
    print(p.name)         # 默认属性
    p.name = ‘sb‘
    print(p.name)
    print(‘==主开始‘)
进程的其他参数

六.僵尸进程和孤儿进程

基于UNIX环境(linux,macOs)

二.守护进程

p.daemon = True,将子进程p设置为守护进程,只要主进程结束(严格来说应该是主进程中的任务执行完,而非主进程结束),守护进程也跟着结束

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读