线程的定义
线程是CPU可调度的最小单位中,被包含在进程中,是进程中实际的动作单位。一个进程中可以拥有N多个线程并发执行,而每个线程并行执行不同的任务
函数式创建线程
语法
t=Thread(group,target,name,args,kwargs)
参数说明:
group:创建线程对象的进程组
target:创建的线程对象所要执行的目标函数
name:创建线程对象的名称,默认为Tread-n
args:用元组以位置参数的形式传入target对应函数的参数
kwargs:用字典以关键字参数的形式传入target对应函数的参数
import threading
from threading import Thread
import time
def test():
for i in range(2):
time.sleep(1)
print(f'线程:{threading.current_thread().name}在执行')
if __name__ == '__main__':
start = time.time()
print('主线程正在运行')
lst=[Thread(target=test) for i in range(3)]
for i in lst:
i.start()
i.join()
print(f'共花费:{time.time() - start}')
输出
主线程正在运行
线程:Thread-1 (test)在执行
线程:Thread-1 (test)在执行
线程:Thread-2 (test)在执行
线程:Thread-2 (test)在执行
线程:Thread-3 (test)在执行
线程:Thread-3 (test)在执行
共花费:6.004777908325195
继承式创建线程
import threading
from threading import Thread
import time
class MyThread(Thread):
def run(self):
for i in range(2):
time.sleep(1)
print(f'线程:{threading.current_thread().name}在执行')
if __name__ == '__main__':
start = time.time()
print('主线程开始执行')
lst = [MyThread() for i in range(3)]
for i in lst:
i.start()
i.join()
print(f'共花费:{time.time() - start}')
输出
主线程开始执行
线程:Thread-1在执行
线程:Thread-1在执行
线程:Thread-2在执行
线程:Thread-2在执行
线程:Thread-3在执行
线程:Thread-3在执行
共花费:6.003823280334473
线程之间的通信
线程与进程不同的是,多个线程可以共享进程的资源
import threading
from threading import Thread
import time
# 库存
num=100
# 出库
def get_out_storage():
global num
num-=20
print('出库:', 20)
# 入库
def put_in_storage():
global num
num+=10
print('入库:',10)
if __name__ == '__main__':
print('主线程开始执行')
get_out=Thread(target=get_out_storage)
put_in=Thread(target=put_in_storage)
get_out.start()
put_in.start()
put_in.join()
get_out.join()
print(num)
print('主线程执行结束')
输出:
主线程开始执行
出库: 20
入库: 10
90
主线程执行结束
线程安全问题
多个线程在操作共享数据是,会产生的超卖的问题
通过锁来解决多线程产生的数据安全问题
语法:
import threading
from threading import Thread,Lock
lock_obj=Lock()
lock_obj.acquire() # 加锁
# do something
lock_obj.release() # 释放锁
demo
import threading
from threading import Thread,Lock
import time
# 库存
num=100
lock_obj=Lock()
# 出库
def get_out_storage():
global num
lock_obj.acquire() # 加锁
num-=1
print(f'{threading.current_thread().name}--出库:1,库存剩余:{num}')
lock_obj.release() # 释放锁
# 入库
def put_in_storage():
global num
lock_obj.acquire() # 加锁
num+=1
print(f'{threading.current_thread().name}--入库:1,库存剩余:{num}')
lock_obj.release() # 释放锁
if __name__ == '__main__':
for i in range(6):
get_out = Thread(target=get_out_storage)
get_out.start()
for i in range(10):
put_in=Thread(target=put_in_storage)
put_in.start()
输出
Thread-1 (get_out_storage)–出库:1,库存剩余:99
Thread-2 (get_out_storage)–出库:1,库存剩余:98
Thread-3 (get_out_storage)–出库:1,库存剩余:97
Thread-4 (get_out_storage)–出库:1,库存剩余:96
Thread-5 (get_out_storage)–出库:1,库存剩余:95
Thread-6 (get_out_storage)–出库:1,库存剩余:94
Thread-7 (put_in_storage)–入库:1,库存剩余:95
Thread-8 (put_in_storage)–入库:1,库存剩余:96
Thread-9 (put_in_storage)–入库:1,库存剩余:97
Thread-10 (put_in_storage)–入库:1,库存剩余:98
Thread-11 (put_in_storage)–入库:1,库存剩余:99
Thread-12 (put_in_storage)–入库:1,库存剩余:100
Thread-13 (put_in_storage)–入库:1,库存剩余:101
Thread-14 (put_in_storage)–入库:1,库存剩余:102
Thread-15 (put_in_storage)–入库:1,库存剩余:103
Thread-16 (put_in_storage)–入库:1,库存剩余:104