【学习笔记】python—多任务编程(进程)


之前决定要把每天学习的内容记录下来,坚持了几天后发现做这事很浪费时间,于是渐渐的就落下了。

现在重新开始,并不是因为“可以帮助别人”这种高大上的理由(毕竟小白一个,如果很幸运刚好被需要,那确实是很值得的开心的事情),仅仅是因为害怕 习惯性放弃。做过的事情,有余力做完,且算得上是一件不错的事,不做下去始终是遗憾。
 


目录

1、多任务

1.1 进程的使用

1.1.1多进程实现多任务

1.1.2执行带有参数的任务

1.1.3 GET PROCESS ID

 1.1.4. PROCESS NOTES


1、多任务

 好处:充分利用cpu资源,提高程序的执行效率

            方式:并发 并行

            并发:在意短时间内交替执行

            并行:同时执行多个任务

实现多任务的方法:进程、线程

  进程: 一个正在运行的程序或者软件   操作系统进行资源分配的基本单位。
            (操作系统按按进程分配资源 有一个进程就会分配一份内存资源)

进程:并发、并行

             线程: 程序进程中执行代码的分支。 线程工作需要 cpu 的调度。CPU调度的基本单位。

线程:一定是并发

             关系: 一个程序运行后至少有一个进程,一个进程默认有一个线程。线程依附在进程里,没有进程就没有线程。
            一个进程可以有多个线程。

1.1 进程的使用

1.1.1多进程实现多任务

# 多进程的使用
import multiprocessing
import time


def work_one():
    for i in range(2):
        print("执行任务一")
        time.sleep(0.2)

def work_two():
    print("执行任务二")
# 在主模块中创建进程
if __name__=="__main__":

    # 1、创建进程对象 指定执行任务
    # 格式:multiprocessing.Process(group=None[,target[,name[,args[,kwargs]]]])
    # group  目前只能是 None
    # target 指定要执行的任务
    # name  给进程命名(默认是process_n)

    sub_process_one = multiprocessing.Process(group=None,target=work_one,)
    sub_process_two = multiprocessing.Process(group=None,target=work_two)

    # 2、启动进程对象
    sub_process_one.start()
    sub_process_two.start()

"""
执行结果:
    执行任务二
    执行任务一
    执行任务一

    Process finished with exit code 0    
"""

1.1.2执行带有参数的任务

Process传参方式

    1.args:以元的方式传参  (only one element ,

               按位传参,传参顺序和参数顺序一致。

    2.kwargs:以字典的方式传参{key:value...}

             字典中的key 一定要和参数保持一致。顺序可以不一致。

import multiprocessing


def test(name, age):
    print(name)
    for i in range(count):

if __name__ == '__main__':

    # 创建子进程
    # 元组如果只有一个元素,那么元素后面的逗号不能省略
    # args: 表示以元组方式给执行任务传参数, 实际上是按照函数位置参数进行传参的。
    sub_process = multiprocessing.Process(target=test, args=(3, "xiahua"),name="sub_process")
    sub_process.start()

    # kwargs: 表示以字典方式给执行任务传参数, 实际上是按照函数关键字传参的。
    # sub_process = multiprocessing.Process(target=task, kwargs={"name":"xiaohua", "age":18})
    # sub_process.start()

 

1.1.3 GET PROCESS ID

os.getpid()   当前进程编号

           os.getppid()   当前进程父进程编号

在进程所执行的任务代码中获取。

获取当前代码的进程对象 multiprocessing.current_process()

所有的代码都是在进程中的线程中执行的,所以所有当前执行的代码都有自己的进程和线程。

 

import multiprocessing
import os


def work_one():
    print("任务一")
    # 获取当前代码进程对象
    work_one_process = multiprocessing.current_process()

    # 输出当前代码进程对象
    print(work_one_process)

    # 获取当前代码的进程对象的进程编号
    work_one_pid = os.getpid()

    # 获取当前代码进程对象的父进程编号
    work_one_ppid = os.getppid()

    # 打印进程编号
    print("work_one_pid:",work_one_pid)

    # 打印父进程编号
    print("work_one_ppid:",work_one_ppid)


def work_two():
    print("任务二")

    # 获取执行当前代码的进程对象
    work_two_process = multiprocessing.current_process()

    # 打印进程对象
    print("work_two_process:",work_two_process)

    # 获取进程编号
    work_two_pid = os.getpid()

    # 打印进程编号:
    print("work_two_pid:",work_two_pid)

    # 获取父进程编号
    work_two_ppid = os.getppid()

    #打印父进程编号
    print("work_two_ppid:",work_two_ppid)

if __name__=="__main__":

    # 获取当前代码进程对象
    main_process = multiprocessing.current_process()
    print("main_process:",main_process)
    # 获取当前进程的编号
    main_pid = os.getpid()
    print("main_pid:",main_pid)

    sub_process_one = multiprocessing.Process(group=None, target = work_one, name="sub_process_one")

    sub_process_two = multiprocessing.Process(group=None, target = work_two, name="sub_process_two")
    print("sub_process_one:", sub_process_one)
    print("sub_process_two:", sub_process_two)


    sub_process_two.start()
    sub_process_one.start()

"""
执行结果:
    /usr/bin/python3.5 /home/python/untitled/02-获取进程编号.py
    main_process: <_MainProcess(MainProcess, started)>
    main_pid: 5491
    sub_process_one: <Process(sub_process_one, initial)>
    sub_process_two: <Process(sub_process_two, initial)>
    任务二
    work_two_process: <Process(sub_process_two, started)>
    work_two_pid: 5494
    work_two_ppid: 5491
    任务一
    <Process(sub_process_one, started)>
    work_one_pid: 5495
    work_one_ppid: 5491

    Process finished with exit code 0
   
"""

通过进程编号可以看出子进程是由哪个父进程创建。


 1.1.4. PROCESS NOTES

进程间不共享全局变量。

父进程默认需等所有子进程结束才结束。

because:进程是操作系统分配资源的基本单位。操作系统会给每一个进程分配一份内存资源。

即每个进程所占用的内存资源是相互独立的。当多个子进程操作操作一个名为XXX的全局变量时,实质操作的是自己内存的一个变量不会影响其他进程。

不可共享全局变量的原理
不可共享全局变量原理图
import multiprocessing
import time


def test(num):
    """
    此函数执行完需要unm*0.2s
    :param num:
    """
    for i in range(num):
        print("sub_process正在工作阶段%d" %i)
        time.sleep(0.2)

# 创建子进程
# args:采用元组方式传参,test()执行时间大约0.6s
sub_process = multiprocessing.Process(group=None, target=test, args=(3,))

# 启动子线程
sub_process.start()

# 主线程延时0.4s
time.sleep(0.4)

print("代码执行到此处,主线程结束")

"""
执行结果:
    sub_process正在工作阶段0
    sub_process正在工作阶段1
    代码执行到此处,主线程执结束
    sub_process正在工作阶段2

    Process finished with exit code 0
    
"""

显然:主线程结束后,并没有立即退出,而是在等待子线程执行。

 

若想主进程结束就退出程序:

设置守护主进程:子进程对象.daemon = True

销毁子进程:子进程对象.terminate()

mport multiprocessing
import time


def test(3):
    """
    此函数执行完大约需要0.6s
    :param num:
    """
    for i in range(num):
        print("sub_process正在工作阶段%d" %i)
        time.sleep(0.2)

# 创建子进程

sub_process = multiprocessing.Process(group=None, target=test)
# 设置主线程守护,主线程退出子线程销毁,停止运行。
sub_process.daemon = True

# 启动子线程
sub_process.start()

# 主线程延时0.4s
time.sleep(0.4)

print("代码执行到此处,主线程结束")

"""
执行结果:
    sub_process正在工作阶段0
    sub_process正在工作阶段1
    代码执行到此处,主线程执结束
   
    Process finished with exit code 0
    
"""

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值