线程的概念
1.线程的介绍
在Phon中,想要实现多任务除了使用进程,还可以使用线程来完成,线程是实现多任务的另外一种方式,线程是使用资源的最小单元,依附于进程
2.线程的概念
线程是进程中执行代码的一个分支,每个执行分支(线程)要想工作执行代码需要cpu进行调度·也就是说
线程是cpu调度的基本单位,每个进程至少都有一个线程,而这个线程就是我们通常说的主线程
3.线程的作用
程序启动后默认会有一个主线程,程序员自己创建的线程可以称为子线程,多线程可以完成多个任务,需要用CPU调度来完成
4.单线程和多线程
做个简单的比喻:进程=火车,线程=车厢
线程在进程下行进(单纯的车厢无法运行)
一个进程可以包含多个线程(一辆火车可以有多个车厢)不同进程间数据很难共享
(一辆火车上的乘客很难换到另外一辆火车,比如站点换乘)
同一进程下不同线程间数据很易共享(A车厢换到B车厢很容易)
进程要比线程消耗更多的计算机资源(采用多列火车相比多个车厢更耗资源)进程间不会相互影响,
一个线程挂掉将导致整个进程挂掉(一列火车不会影响到另外一列火车,但是如果一列火车上中间的一节车厢着火了,
将影响到所有车厢)进程可以拓展到多机,
进程最多适合多核(不同火车可以开在多个轨道上,同一火车的车厢不能在行进的不同的轨道上)进程使用的内存地址可以上锁
,即一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。
(比如火车上的洗手间)
-"互斥锁"进程使用的内存地址可以限定使用量
(比如火车上的餐厅,最多只允许多少人进入,如果满了需要在门口等,等有人出来了才能进去)-“信号量”
5.多线程(多任务实现的方式)
1 import threading
2 threading.Thread(target = xxx)
3 start()
6.线程执行带有参数的任务
import threading
def dance(count):
for i in range(count):
print('跳舞',i)
if __name__ == '__main__':
#带有参数的函数:
#args:元组
#kwargs:字典
my_dance = threading.Thread(target=dance,args=(5,))
# my_dance = threading.Thread(target=dance, kwargs={"nums":6})
my_dance.start()
7.线程的注意点介绍
1.线程之间执行是无序的
2.主线程会等待所有的子线程执行结束再结束
3.线程之间共享全局变量
4.线程之间共享全局变量数据出现错误问题
8.守护线程
守护主线程:
·守护主线程就是主线程退出子线程销毁不再执行
设置守折主线程有两种方式
1. threading Thread(target=show_info, daemon=True)
2. 线程对象.setDaemon(True)
示例代码:
import threading
import time
def show_info():
for i in range(5):
print('test',i)
time.sleep(0.5)
if __name__ == '__main__':
#创建子线程守护主线程,让子线程随着主线程的结束而结束
#daemon=True守护主线程
#守护主线程方式1
sub_thread = threading.Thread(target=show_info,daemon=True)
#设置成为守护主线程,主线程退出后子线程直接销毁不再执行子线程的代码
#方式2 对象.setDaemon(True)
sub_thread = threading.Thread(target=show_info)
sub_thread.setDaemon(True)
sub_thread.start()
time.sleep(1)
print('over')
9.线程共享全局变量
import threading
g_num = 0
def sum_num1():
global g_num
# for 循环让值最终加到100000
for i in range(100000):
g_num += 1
print("sum_num1:",g_num)
def sum_num2():
global g_num
# for 循环让值最终加到100000
for i in range(100000):
g_num += 1
print("sum_num2:", g_num)
if __name__ == '__main__':
sub_num1 = threading.Thread(target=sum_num1)
sub_num2 = threading.Thread(target=sum_num2)
sub_num1.start()
sub_num2.start()
10.互斥锁
线程同步的方式:
1.线程等待(join) = 第一个线程执行完毕后再执行第二个线程,即同一时刻只能执行一个任务
2.互斥锁 = 对共享数据进行锁定,保证同一时刻只能有一个线程去操作,第一个线程先执行,没有执行的线程需要等待,等互斥锁使用完释放后,其他线程再一个个去执行threading模块中定义了Lock 变量 ,这个变量本质就是个函数,通过调用这个函数就可以获取一把互斥锁互斥锁使用步骤:
#创建锁 写在全局里my_lock = threading.Lock()
#上锁
写在函数内部上方my_lock.acquire()
#释放锁
写在函数内部下方my_lock.release()
注意点· acquire和 release方法之间的代码同一时刻只能有一个线程去操作·
如果在调用 acquire方法的时候其他线程已经使用了这个互斥锁,那么此时 acquire方法会堵塞,直到这个互斥锁释放后才能再次上锁

浙公网安备 33010602011771号