python多线程

一、多任务

1、多任务概念:同一时间执行多个任务
2、多任务作用:充分利用CPU的资源,提高程序执行效率
3、多任务的表现形式:
并发:操作系统在执行多任务是交替执行
并行:操作系统会给每个CPU安排一个任务,这两个任务是真正意义上的同时执行

二、进程

在python中,可以用多进程来实现多任务

1、进程概念:是资源分配的最小单位,它是操作系统进行资源分配和调度运行的基本单位, 通俗来说,一个正在运行的程序就是一个进程,例如:正在运行的qq、微信,都是一个进程
2、进程的作用:使用多进程实现多任务的编程
运行起来的程序是进程,一个没有运行的程序叫做程序
注意:一个程序运行后至少有一个进程,也可以有多进程

三、多进程完成多任务

1、进程的创建步骤
(1)导入进程包:import multiprocessing
(2)通过进程类创建进程对象:进程对象=multiprocessing.Process()
(3)启动进程执行任务:进程对象.start()

2、通过进程类创建进程对象:
进程对象=multiprocessing.Process(target=任务名)

参数名 说明
target 执行的目标任务名,这里指的是函数名(方法名)
name 进程名,一般不用设置
group 进程组,目前只能使用None

3、进程创建与启动的代码

#创建子进程
sing_process = multiprocessing.Process(target=sing)
#创建子进程
dance_process = multiprocessing.Process(target=dance)
#启动进程
sing_process.start()
dance_process.start()
import multiprocessing
import time

def sing():
    for i in range(3):
        print("唱歌。。。")
        time.sleep(0.5)

def dance():
    for i in range(3):
        print("跳舞。。。")
        time.sleep(0.5)


if __name__ == '__main__':
    # 创建子进程
    sing_process = multiprocessing.Process(target=sing)
    # 创建子进程
    dance_process = multiprocessing.Process(target=dance)
    # 启动进程
    sing_process.start()
    dance_process.start()

四、进程执行带有参数的任务

参数名 说明
args 以元组的方式给执行任务传参
kwargs 以字典方式给执行任务传参

元祖传参方式:元组传参一定要和参数的顺序保持一致
字典传参方式:字典方式传参中的key一定要和参数名保持一致

import multiprocessing
import time

def sing(num,name):
    for i in range(num):
        print(name)
        print("唱歌。。。")
        time.sleep(0.5)

def dance(num,name):
    for i in range(num):
        print(name)
        print("跳舞。。。")
        time.sleep(0.5)


if __name__ == '__main__':
    # 创建子进程
    # args:使用元组方式给指定任务传参,元租的元素顺序就是任务中的参数顺序
    sing_process = multiprocessing.Process(target=sing,args=(5,"小明"))
    # 创建子进程
    # kwargs:使用字典方式给指定任务传参,key就是参数的名称
    dance_process = multiprocessing.Process(target=dance,kwargs={"name":"传智", "num":3})
    # 启动进程
    sing_process.start()
    dance_process.start()

五、获取进程编号

进程编号的作用:当程序中进程的数量越来越多时,如果没有办法区分主进程和子进程还有不同的子进程,那么就无法进行有效的进程管理,为了方便管理,每个进程都有自己的编号

获取进程编号的两种方式:
1、获取当前进程编号:os.getpid()
2、获取当前父进程编号:os.getppid()

os.getpid()的使用

import os
pid = os.getpid()
print(pid)

os.getppid()的使用

def work():
   #获得当前进程的编号
   print("work进程编:",os.getpid()
   #获得当前父进程的编号
   print("work父进程编:",os.getppid()

python多线程_第1张图片

import multiprocessing
import time
import os

def sing(num,name):
    print("唱歌进程pid:",os.getpid())
    print("唱歌进程的父进程pid:",os.getppid())
    for i in range(num):
        print(name)
        print("唱歌。。。")
        time.sleep(0.5)

def dance(num,name):
    print("跳舞进程pid:", os.getpid())
    print("跳舞进程的父进程pid:", os.getppid())
    for i in range(num):
        print(name)
        print("跳舞。。。")
        time.sleep(0.5)


if __name__ == '__main__':
    print("主进程pid",os.getppid())
    # 创建子进程
    # args:使用元组方式给指定任务传参,元租的元素顺序就是任务中的参数顺序
    sing_process = multiprocessing.Process(target=sing,args=(5,"小明"))
    # 创建子进程
    # kwargs:使用字典方式给指定任务传参,key就是参数的名称
    dance_process = multiprocessing.Process(target=dance,kwargs={"name":"传智", "num":3})
    # 启动进程
    sing_process.start()
    dance_process.start()

六、进程的注意点

主进程会等待所有的子进程执行结束再结束

为了保证子进程能够正常执行,主进程会等所有的子进程执行完成之后再销毁,设置守护主进程的目的是主进程退出子进程销毁,不让主进程再等待子进程去执行

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

if __name__ == '__main__':
    print("主进程pid",os.getppid())
    # 创建子进程
    # args:使用元组方式给指定任务传参,元租的元素顺序就是任务中的参数顺序
    sing_process = multiprocessing.Process(target=sing,args=(5,"小明"))
    # 创建子进程
    # kwargs:使用字典方式给指定任务传参,key就是参数的名称
    dance_process = multiprocessing.Process(target=dance,kwargs={"name":"传智", "num":3})
    # 设置守护主进程,主进程结束子进程自动销毁,不在执行子进程
    sing_process.daemon = True
    # 启动进程
    sing_process.start()
    # dance_process.start()
    time.sleep(0.5)
    print("主进程结束")

七、线程

在python中,想要实现多任务还可以使用多线程来完成

进程是分配资源的最小单位,一旦创建了一个进程就会分配一定的资源,就像两个人聊qq就需要打开两个qq软件,比较浪费资源

线程是程序执行的最小单位实际上进程只负责分配资源,而利用这些资源执行程序的实线程,也就是说进程是线程的容器,一个进程中最少有一个线程来负责执行程序,同时显成自己不拥有系统资源,只需要一点在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源,就像一个qq软件(一个进程)打开两个窗口(两个线程)跟两个人聊天,实现多任务同时也节省了资源

八、多线程完成多任务

1、线程创建步骤
(1)导入线程模块:import threading
(2)通过线程类创建线程对象:线程对象=threading.Thread(target=任务名)
(3)启动线程执行任务:线程对象.start()
2、通过线程类创建线程对象
线程对象=threading.Thread(target=任务名)

参数名 说明
target 执行的目标任务名,这里指的是函数名(方法名)
name 线程名,一般不用设置
group 线程组,目前只能使用None
3、线程创建与启动的代码
#创建子线程
sing_process = threading.Thread(target=sing)
#创建子线程
dance_process = threading.Thread(target=dance)
#启动线程
sing_process.start()
dance_process.start()

九、线程执行带有参数的任务

1、线程执行带有参数的任务

参数名 说明
args 以元组的方式给执行任务传参
kwargs 以字典方式给执行任务传参

元祖传参方式:元组传参一定要和参数的顺序保持一致
字典传参方式:字典方式传参中的key一定要和参数名保持一致

十、主线程和子线程的结束顺序

主线程会等待所有的子线程执行结束后,主线程再结束

1、设置守护主线程
要想主线程不等待子线程执行完成,可以设置守护主线程

# 设置守护主线程方式1:deamon=True  
work_thread = threading.Thread(target=work,deamon=True)
# 设置守护主线程方式2:
work_thread.setDaemon(True)
work_thread.start()

十一、线程间的执行顺序

多线程之间执行是无序的:由cpu调度决定的

十二、进程和线程的对比

1、关系对比:
(1)线程是依附在进程里面的,没有进程就没有线程
(2)一个进程默认提供一个线程,进程可以创建多个线程
2、区别对比:
(1)创建进程的资源开销要比创建线程的资源开销大
(2)进程是操作系统资源分配的基本单位,线程数cpu调度的基本单位
(3)线程不能独立执行,必须依存于进程中
3、优缺点对比
(1)进程优缺点:
优点:可以用多核
缺点:资源开销大
(2)线程优缺点:
优点:资源开销小
缺点:不能使用多核

你可能感兴趣的:(python基础,python)