python进阶学习--进程

python进阶学习

进程

文章目录

  • python进阶学习
    • 进程
      • 进程的概念:
      • 进程的特征
      • 在python中进程的操作
          • 注意:1. 必须使用关键字方式来指定参数;2. args指定的为传给target函数的位置参数,是一个元祖形式,必须有逗号。
          • 参数介绍:
      • 进程池
      • 进程操作相关代码

进程的概念:

  1. 进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。
  2. 进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时(操作系统执行之),它才能成为一个活动的实体,我们称其为进程。
  3. 进程是操作系统中最基本、重要的概念。是多道程序系统出现后,为了刻画系统内部出现的动态情况,描述系统内部各道程序的活动规律引进的一个概念,所有多道程序设计操作系统都建立在进程的基础上。

进程的特征

  1. 动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
  2. 并发性:任何进程都可以同其他进程一起并发执行。
  3. 独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位。
  4. 异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进。

在python中进程的操作

from multiprocess import Process

process模块是一个创建进程的模块,借助这个模块可以完成进程的创建

语法:Process([group [, target [, name [, args [, kwargs]]]]])

由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)。

注意:1. 必须使用关键字方式来指定参数;2. args指定的为传给target函数的位置参数,是一个元祖形式,必须有逗号。
参数介绍:
group: 参数未使用,默认值为None。
target: 表示调用对象,即子进程要执行的任务。
args: 表示调用的位置参数元祖。
kwargs: 表示调用对象的字典。如kwargs = {‘name’:Jack, ‘age’:18}。
name: 子进程名称。
返回值: 实例化对象

Process属性方法的介绍

start() 启动进程,调用进程中的run()方法。
run() 进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法 。
terminate() 强制终止进程,不会进行任何清理操作。如果该进程终止前,创建了子进程,那么该子进程在其强制结束后变为僵尸进程;如果该进程还保存了一个锁那么也将不会被释放,进而导致死锁。使用时,要注意。
join([timeout]) 主线程等待子线程终止。timeout为可选择超时时间;需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程 。
name 进程名称。
pid 进程pid

注意:多个进程同时执行的顺序是随机的,不根据执行顺序的来。

进程池

进程池的好处 可以实现进程的复用,防止进程的空闲
非阻塞式进程池 1.在先进入的任务中,有一个结束,那么就会分配新任务,新任务与完成的那个任务的进程id一样 2. 全部添加到的队列中立刻返回,并没有等待其他进程完毕,谁先完成谁回调,回调函数是等待任务完成菜调用
阻塞式进程池 一个一个进来执行,添加一个执行一个,一个任务不结束另一个无法进来,不能一起工作

进程操作相关代码

  1. 进程基础
import os
from multiprocessing import Process
from time import sleep


def task1(*a):
    while True:
        sleep(1)
        print("这是任务1", a, os.getpid())


def task2(*a):
    while True:
        sleep(1)
        print("这是任务2", a, os.getpid())


'''
    主进程在这是用来启动两个子进程 
    process = Process(target=函数名,name=进程名,arg=给函数传递的参数)
    
    对象调用的方法
    process.start() 运行进程操作
    process.run() 运行函数,但不启动进程
    process.terminate() 终止进程
'''
number = 0
if __name__ == '__main__':
    p1 = Process(target=task1, name="任务1", args='aa')
    p2 = Process(target=task2, name="任务2", args='bb')
    p1.start()
    p2.start()
    while True:
        number += 1
        sleep(0.2)
        if number == 100:
            p1.terminate()
            p2.terminate()
            break
        else:
            print(number)
    print("*" * 100)

  1. 主进程和子进程同时执行
import os
from multiprocessing import Process
from time import sleep


def task1(a):
    while True:
        sleep(1)
        print("我是子进程1", os.getpid(),a)


def task2(b):
    while True:
        sleep(1)
        print("我是子进程2", os.getpid(),b)


if __name__ == '__main__':
    p1 = Process(target=task1, name='任务1',args=('aa',))
    p2 = Process(target=task2, name='任务1',args=('bb',))
    p1.start()
    p2.start()
    while True:
        sleep(1)
        print('我是父进程', os.getpid())

  1. 自定义进程
from multiprocessing import Process


class MyProcess(Process):
    def __init__(self, name):
        super().__init__()
        self.name = name

    def run(self):
        n = 1
        while True:
            n += 1
            print("进程名字:", self.name, n)


if __name__ == '__main__':
    p1 = MyProcess('mike1')
    p2 = MyProcess('mike2')
    p1.start()
    p2.start()

  1. 非阻塞式进程池
import os
from multiprocessing import Pool

import time
from random import random

'''
    进程池的好处就可以实现进程的复用,防止进程的空闲
    非阻塞式进程池在先进入的任务中,有一个结束,那么就会分配新任务,新任务与完成的那个任务的进程id一样
    全部添加到的队列中立刻返回,并没有等待其他进程完毕,谁先完成谁回调,回调函数是等待任务完成菜调用
'''


def task_def(task_name):
    print("开始做任务", task_name)
    start = time.time()
    time.sleep(random() * 2)
    end = time.time()
    return task_name, "任务结束了,用时", (end - start), os.getpid()


list_task = []


def callback_def(n):
    list_task.append(n)


if __name__ == '__main__':
    pool = Pool(5)
    tasks = ['唱歌', '跳舞', '跑步', '篮球', 'LOL', '英雄联盟', '敲代码']
    for task in tasks:
        pool.apply_async(task_def, args=(task,), callback=callback_def)

    pool.close()  # 添加任务结束
    pool.join()  # 防止主进程结束导致子进程结束

    for i in list_task:
        print(i)

  1. 阻塞式进程池
import os
from multiprocessing import Pool

import time
from random import random

'''
    进程池的好处就可以实现进程的复用,防止进程的空闲
    非阻塞式进程池:
    1.
        在先进入的任务中,有一个结束,那么就会分配新任务,新任务与完成的那个任务的进程id一样
    2.  
        全部添加到的队列中立刻返回,并没有等待其他进程完毕,谁先完成谁回调,回调函数是等待任务完成菜调用
    阻塞式进程池:
    1.
        一个一个进来执行,添加一个执行一个,一个任务不结束另一个无法进来,不能一起工作
    
'''


def task_def(task_name):
    print("开始做任务", task_name)
    start = time.time()
    time.sleep(random() * 2)
    end = time.time()
    print(task_name, "任务结束了,用时", (end - start), os.getpid())


list_task = []


def callback_def(n):
    list_task.append(n)


if __name__ == '__main__':
    pool = Pool(5)
    tasks = ['唱歌', '跳舞', '跑步', '篮球', 'LOL', '英雄联盟', '敲代码']
    for task in tasks:
        pool.apply(task_def, args=(task,))

    pool.close()  # 添加任务结束
    pool.join()  # 防止主进程结束导致子进程结束

你可能感兴趣的:(python)