您现在的位置是:首页 >技术杂谈 >多线程、协程和多进程并发编程网站首页技术杂谈
多线程、协程和多进程并发编程
37.1 如何通俗理解线程和进程?
进程:进程就是正在执⾏的程序。
线程:是程序执⾏的⼀条路径, ⼀个进程中可以包含多条线程。
通俗理解:例如你打开抖⾳,就是打开⼀个进程,在抖⾳⾥⾯和朋友聊天就是开启了⼀条线程。
再举⼀个例⼦:
在某⻝堂打饭的时候,此⻝堂安排三个打饭⼤妈打饭,所有同学依次排成三个队伍,每个打饭⼤ 妈相当于⼀个线程。
这个⻝堂相当于⼀个进程,他⼀共有三个打饭⼤妈,相当于进程⾥有三个线程。
两者之间的关系:
⼀个进程⾥⾯可以有多条线程,⾄少有⼀条线程。
⼀条线程⼀定会在⼀个进程⾥⾯。
关于协程我会放在后⾯讲完线程和进程时再讲解。
37.2 Python如何启动⼀个线程?
⼀般的,程序默认执⾏只在⼀个线程,这个线程称为主线程,例⼦演示如下:
导⼊线程相关的模块 threading:
import threadin
threading的类⽅法 current_thread()返回当前线程:
t = threading.current_thread()
print(t)
看到 MainThread,验证了程序默认是在MainThead中执⾏。
t.getName()获得这个线程的名字
其他常⽤⽅法,t.ident获得线程id
is_alive() 判断线程是否存活
那么,如何创建⾃⼰的线程呢?
下⼀节课我们了解:如何在Python中创建⼀个新线程
my_thread = threading.Thread()
创建线程的⽬的是告诉它帮助我们做些什么,做些什么通过参数target传⼊,参数类型为 callable,函数就是可调⽤的
def print_i(end):
for i in range(end):
print(f'打印i={i}')
my_thread = threading.Thread(target=print_i, args=(10,))
my_thread线程已经全副武装,但是我们得按下发射按钮,启动start(),它才开始真正起⻜。
my_thread.start()
打印结果如下,其中args指定函数print_i需要的参数i,类型为元祖。
打印i=0 打印i=1 打印i=2 打印i=3 打印i=4 打印i=5 打印i=6 打印i=7 打印i=8 打印i=9
⾄此,多线程相关的核⼼知识点,已经总结完毕。但是,仅仅知道这些,还不够!光纸上谈兵, 当然远远不够。
37.4 【案例】如何理解多线程的⼯作(交替获得时间 ⽚)?
为了更好解释多线程之间的⼯作,开辟3个线程,装到threads中
import time from datetime import datetime import threading
def print_time(): for _ in range(5): # 在 每 个 线 程 中 打 印 5 次
time.sleep(0.1) # 模 拟打 印 前 的相 关 处 理 逻辑
print('当前线程%s,打印结束时间为:%s'%(threading.current_thread().getName(
threads = [threading.Thread(name='t%d'%(i,),target=print_time) for i in range(3)]
[t.start() for t in threads]
打印结果如下,t0,t1,t2三个线程,根据操作系统的调度算法,轮询获得CPU时间⽚,注意观察:
37.5 【案例】如何理解多线程抢夺同⼀个变量?
多线程编程,存在抢夺同⼀个变量的问题。
⽐如下⾯例⼦,创建的10个线程同时竞争全局变量 a :
import threading
a = 0
def add1():
global a
a += 1
print('%s adds a to 1: %d'%(threading.current_thread().getName(),a))
threads = [threading.Thread(name='t%d'%(i,),target=add1) for i in range(10)] [t.start() for t in threads]