前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python多任务 - 进程

Python多任务 - 进程

原创
作者头像
忆想不到的晖
修改2021-04-06 11:28:25
4870
修改2021-04-06 11:28:25
举报
文章被收录于专栏:hui

了解进程(Process)

对于进程的定义,从不同的角度可以有不同的定义

  • 进程是程序的一次执行
  • 进程是一个程序及其数据在处理机上顺序执行时所发生的活动
  • 进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配合调度的一个独立单位

程序是指令、数据及其组织形式的描述,进程是程序的实体

进程是进程实体的运行过程,系统进行资源分配合调度的一个独立单位。

举例说明:

程序:例如 xxx.py 这是程序,是一个静态的。

进程:一个程序运行起来后,代码 + 用到的资源称之为进程,它是操作系统分配资源的独立单位。

<img src="https://img-blog.csdnimg.cn/20200930162820111.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjI5ODU3,size_16,color_FFFFFF,t_70#pic_center" alt="任务管理器" title="任务管理器" style="zoom: 67%;" />

进程的状态

工作中,任务数往往大于 CPU 的核数,即一定有一些任务正在执行,而另外一些任务在等待 CPU 进行执行,因此导致了有了不同的状态

进程状态图
进程状态图
  • 就绪态:运行的条件都已经慢去,正在等在 CPU 执行
  • 执行态CPU 正在执行其功能
  • 等待态:等待某些条件满足,例如一个程序 sleep 了,此时就处于等待态

Python多进程

GIL(Global Interpreter Lock 全局解释器锁):每个线程在执行的过程中都需要先获取 GIL,保证同一时刻只有一个线程可以执行代码。

由于 GIL(全局解释器锁) 的原因,Python中的多线程是 “伪并行” 无法利用 CPU 多核优势,如果想要充分地使用多核 CPU 的资源,在Python中大部分情况需要使用多进程。Python提供了 multiprocessing 模块来实现多进程。

multiprocessing 创建多进程

multiprocessing 模块就是跨平台版本的多进程模块,提供了一个 Process 类来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另外的事情。

2个while循环一起执行

代码语言:txt
复制
# -*- coding:utf-8 -*-
import time
from multiprocessing import Process		# 首先导入Process类


def run_proc():
    """子进程要执行的代码"""
    while True:
        print("----2----")
        time.sleep(1)


if __name__=='__main__':
    p = Process(target=run_proc)		# 传入要执行的目标函数
    p.start()							# 启动进程
    while True:
        print("----1----")
        time.sleep(1)

运行结果如下:

代码语言:txt
复制
----1----
----2----
----1----
----2----
----1----
----2----
----1----
----2----
----1----
----2----
...

说明

  • 创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用 start() 方法启动

Process语法结构

代码语言:txt
复制
Process([group [, target [, name [, args [, kwargs]]]]])

参数

含义

target

表示调用对象,即子进程要执行的任务

args

给target指定的函数传递的参数,以元组的方式传递 如:args=(1, 2, 'hui', )

kwargs

给target指定的函数传递关键字参数 如:kwargs={'name': 'hui', 'age': 18}

name

给进程设定一个名字,可以不设定

group

指定进程组

Process对象的常用方法

方法

作用

start()

启动子进程实例(创建子进程)

is_alive()

判断进程子进程是否还在活着

join(timeout)

是否等待子进程执行结束,或等待多少秒

terminate()

不管任务是否完成,立即终止子进程

Process对象的常用属性

  • name:当前进程的别名,默认为 Process-N,N为从1开始递增的整数
  • pid:当前进程的pid(进程号)

给子进程指定的函数传递参数

代码语言:txt
复制
# -*- coding:utf-8 -*-
import os
from time import sleep
from multiprocessing import Process


def run_proc(name, age, **kwargs):
    for i in range(10):
        print('子进程运行中,name= %s,age=%d ,pid=%d...' % (name, age, os.getpid()))
        print(kwargs)
        sleep(0.2)

        
def main():
    p = Process(target=run_proc, args=('test',18), kwargs={"m":20})
    p.start()
    sleep(1)  		# 1秒中之后,立即结束子进程
    p.terminate()	# 终止子进程
    p.join()		
    
    
if __name__=='__main__':
    main()

运行结果:

代码语言:txt
复制
子进程运行中,name= test,age=18 ,pid=45097...
{'m': 20}
子进程运行中,name= test,age=18 ,pid=45097...
{'m': 20}
子进程运行中,name= test,age=18 ,pid=45097...
{'m': 20}
子进程运行中,name= test,age=18 ,pid=45097...
{'m': 20}
子进程运行中,name= test,age=18 ,pid=45097...
{'m': 20}

继承Process类创建多进程

创建进程的方式还可以使用类的方式,可以自定义一个类,继承 Process 类,重写run方法,每次实例化这个类的时候,就等同于实例化一个进程对象

代码语言:txt
复制
import time
from multiprocessing import Process
 
    
# 定义进程类
class ClockProcess(Process):
	def __init__(self,interval):
		super().__init__(self)	# 记得加载Process类的__init__()方法
		self.interval = interval
        
	def run(self):
		print('子进程开始执行的时间:{}'.format(time.ctime()))
		time.sleep(self.interval)
		print('子进程结束的时间:{}'.format(time.ctime()))
 

def main():
    # 创建子进程睡眠两秒
	p = ClockProcess(2)
	# 调用子进程
	p.start()
    # 等待子进程结束
	p.join()
	print('主进程结束')
    
    
if __name__=='__main__':
	main()

运行结果

代码语言:txt
复制
子进程开始执行的时间:Sat Oct  3 23:21:20 2020
子进程结束的时间:Sat Oct  3 23:21:22 2020
主进程结束

继承 Process 类,重写run方法,实例化的对象调用 start() 方法就会执行 run() 方法的代码

进程间不共享全局变量

代码语言:txt
复制
# -*- coding:utf-8 -*-
import os
import time
from multiprocessing import Process


nums = [11, 22]


def work1():
    """子进程要执行的代码"""
    print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
    for i in range(3):
        nums.append(i)
        time.sleep(1)
        print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))

        
def work2():
    """子进程要执行的代码"""
    print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))

    
def main():
    p1 = Process(target=work1)
    p1.start()	# 子进程开启
    p1.join()	# 等待子进程执行结束

    p2 = Process(target=work2)
    p2.start()
    
    
if __name__ == '__main__':
    main()

运行结果:

代码语言:txt
复制
in process1 pid=11349 ,nums=[11, 22]
in process1 pid=11349 ,nums=[11, 22, 0]
in process1 pid=11349 ,nums=[11, 22, 0, 1]
in process1 pid=11349 ,nums=[11, 22, 0, 1, 2]
in process2 pid=11350 ,nums=[11, 22]

说明: p1 进程往 num 列表添加的元素,与 p2 进程不共享,p2 进程打印的还是原来的 num[11, 12]

Python多线程、进程对比

对比方式

线程

进程

Python模块

threading

multiprocessing

开启方式

threading.Thread() 继承 Thread

multiprocessing.Process() 继承 Process

共享全局变量

共享

不共享

公众号

新建文件夹X

大自然用数百亿年创造出我们现实世界,而程序员用几百年创造出一个完全不同的虚拟世界。我们用键盘敲出一砖一瓦,用大脑构建一切。人们把1000视为权威,我们反其道行之,捍卫1024的地位。我们不是键盘侠,我们只是平凡世界中不凡的缔造者 。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 了解进程(Process)
    • 进程的状态
    • Python多进程
      • multiprocessing 创建多进程
        • Process语法结构
          • Process对象的常用方法
            • 给子进程指定的函数传递参数
              • 继承Process类创建多进程
                • 进程间不共享全局变量
                • Python多线程、进程对比
                • 公众号
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档