多线程-01

多线程

进程和线程

进程

本质上就是一段程序的运行过程(抽象概念)

最小的资源单位(操作系统分配cpu,内存资源的基本单位)

线程

最小的执行单元(实例),是cpu调度和分派的基本单位

每个线程都有自己的堆栈和局部变量

1.一个程序至少有一个进程,一个进程至少有一个线程。(进程可以理解为线程的容器),一个进程里可以开辟多个线程和进程

2.进程在执行过程中拥有独立的内存单元,而多个线程共享这个进程的内存,从而极大地提高了程序的运行效率

3.一个线程(主线程创建子线程)可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行

并发&并行

并发:系统具有处理多个任务的能力,cpu疯狂切换(单核)

扫描二维码关注公众号,回复: 7142229 查看本文章

并行:系统具备同时处理多个任务的能力(多核)

同步&异步

同步:我煮饭,我等煮好饭去炒菜--等

异步:我煮饭的过程中,可以去炒菜--不等

python解释器的GIL锁

无论你启多少个线程,你有多少个cpu, Python在执行的时候会淡定的在同一时刻只允许一个线程运行

一个python进程同一时间只有一个线程能被cpu调用(多核对它基本没有用)

但是可以开启多个进程,然后每个进程就可以各有一个线程丢给一个cpu,来实现并行

计算密集型:多进程效率高

I/O密集型:多线程效率高(IO过程中cpu会有空闲时间,可以利用空闲时间做别的任务)

多线程或者(多进程+携程)用于IO密集型,如socket,爬虫,web

多进程用于计算密集型,如金融分析(但是不推荐)

python中的多线程

例1

如下有三个线程,一个主线程,主线程开辟了两个子线程

主线程最先运行完毕,t1子线程运行了3秒,t2子线程运行了6秒

整个进程花费了6秒多一点结束

import threading
import time

def zx(t,s):
    time.sleep(s)
    print(t)


if __name__ == '__main__':
    t1=threading.Thread(target=zx,kwargs={"t":"t1","s":3})
    t1.start()

    t1=threading.Thread(target=zx,kwargs={"t":"t2","s":6})
    t1.start()

    print("main")

main
t1
t2

Process finished with exit code 0
例2

和上面一样的知识点

import time
import threading

def music():
    print("开始听歌")
    time.sleep(3)
    print("停止听歌")

def game():
    print("开始玩游戏")
    time.sleep(6)
    print("停止玩游戏")

if __name__ == '__main__':
    t1=threading.Thread(target=music)
    t2=threading.Thread(target=game)
    t1.start()
    t2.start()

    print("main")

开始听歌
开始玩游戏
main
停止听歌
停止玩游戏

Process finished with exit code 0

常用方法

# run():  线程被cpu调度后自动执行线程对象的run方法
# start():启动线程活动。
# isAlive(): 返回线程是否活动的。
# getName(): 返回线程名。
# setName(): 设置线程名。

threading模块提供的一些方法:
# threading.currentThread(): 返回当前的线程变量。
# threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
# threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

join() 线程等待

join():在子线程完成运行之前,这个子线程的父线程将一直被阻塞。

看懂下面代码者,方可大成

join()相当于,执行完这个子线程,再去执行主线程下面的代码

import time
import threading

def music():
    print("开始听歌")
    time.sleep(3)
    print("停止听歌")

def game():
    print("开始玩游戏")
    time.sleep(6)
    print("停止玩游戏")

if __name__ == '__main__':
    t1=threading.Thread(target=music)
    t2=threading.Thread(target=game)
    t1.start()

    t1.join()

    t2.start()

    t2.join()

    print("main")

开始听歌
停止听歌
开始玩游戏
停止玩游戏
main

Process finished with exit code 0

setDaemon()守护线程

setDaemon(True):

将线程声明为守护线程,必须在start() 方法调用之前设置,当我们 在程序运行中,执行一个主线程,主线程运行完毕,想退出时,会检验子线程是否完成。如果子线程未完成,则主线程会等待子线程完成后再退出。但是有时候我们需要的是 只要主线程完成了,不管子线程是否完成,都要和主线程一起退出,这时就可以 setDaemon方法啦

例1

当主线程运行完毕,去检验t1和t2,发现他们都是守护线程,直接退出

import time
import threading

def music():
    print("开始听歌")
    time.sleep(3)
    print("停止听歌")

def game():
    print("开始玩游戏")
    time.sleep(6)
    print("停止玩游戏")

if __name__ == '__main__':
    t1=threading.Thread(target=music)
    t2=threading.Thread(target=game)
    t1.setDaemon(True)
    t2.setDaemon(True)
    t1.start()
    t2.start()
    print("main")

开始听歌
开始玩游戏
main

Process finished with exit code 0

例2

当主线程运行完毕,去检验t1和t2,发现t1不是守护线程,t2是守护线程,t1耗时3秒,t1执行完毕,直接退出,因为t2耗时6秒,还是守护线程,主线程不用管它

import time
import threading

def music():
    print("开始听歌")
    time.sleep(3)
    print("停止听歌")

def game():
    print("开始玩游戏")
    time.sleep(6)
    print("停止玩游戏")

if __name__ == '__main__':
    t1=threading.Thread(target=music)
    t2=threading.Thread(target=game)
    t2.setDaemon(True)
    t1.start()
    t2.start()
    print("main")

开始听歌
开始玩游戏
main
停止听歌

Process finished with exit code 0

猜你喜欢

转载自www.cnblogs.com/zx125/p/11440563.html
今日推荐