线程理论及threading模块
线程理论
线程和进程在使用方式和调度策略上十分的相似,两者的本质区别在于
- 进程:进程是资源单位,表示一块内存空间
- 线程:线程是执行单位,真正的执行代码指令
一个进程中可以有多条线程,就像一个车间中可以有多条作业线,一个进程中至少有一个线程。
开设进程所要消耗的资源更大,而一个进程下开设线程就会快很多。
同一个进程下的多线程的数据是共享的,并不像多进程一样数据隔离。
创建线程的代码实现
方式1
from threading import Thread
import time
def task(name):
print(f'{name} is running')
time.sleep(0.1)
print(f'{name} is over')
start_time = time.time()
print(time.time() - start_time)
t_list = []
for i in range(100): # 连续开100个线程
t = Thread(target=task, args=('用户%s'%i,))
t.start()
t_list.append(t) # 将线程存到列表
for t in t_list:
t.join() # 遍历等待所有线程结束后再执行后续代码
print(time.time() - start_time) # 0.11784076690673828
t = Thread(target=task, args=('jason',))
t.start()
print('主线程')
创建线程时只将提交的任务开设一个新的执行单位执行,不会像开进程一样将整个py文件的资源重新运行一遍,所以不必加main语句来判断执行文件。
这里也可以看见对于执行时间原本需要0.1秒任务,同时开启100个线程的用时也就多一点,而开100个进程的执行时间就会长很多,因为开设进程消耗的时间和资源都较大。
方式2
from threading import Thread
import time
class MyThread(Thread): # 也是派生类的方法
def run(self): # 任务
print('run is running')
time.sleep(1)
print('run is over')
obj = MyThread()
obj.start()
print('主线程')
线程的诸多特性
join方法
与进程的join方法一致,是让主线程等待子线程结束后再执行后续代码。
from threading import Thread
import time
def task(name):
print(f'{name} is running')
time.sleep(1)
print(f'{name} is over')
t = Thread(target=task, args=('jason', ))
t.start()
t.join()
print('主线程')
线程数据共享
import time
from threading import Thread
money = 1001
def task():
time.sleep(0.2)
global money
money -= 100
t_list = []
for i in range(10):
t = Thread(target=task)
t.start()
t_list.append(t)
for t in t_list:
t.join()
print(money) # 1
event事件
事件的作用是帮助我协调多个线程间的某些动作的发生顺序。
代码实现如下。
from threading import Thread, Event
import time
event = Event() # 创造了一个事件对象
def light():
print('红灯亮着的 所有人都不能动')
time.sleep(3)
print('绿灯亮了 油门踩到底 给我冲!!!')
event.set() # 事件发出信号
def car(name):
print('%s正在等红灯' % name)
event.wait() # 等待信号发出再执行后续代码
print('%s加油门 发车了' % name)
t = Thread(target=light) # 先启动红绿灯计时
t.start() # light中等待3秒后会亮起绿灯,同时让event发射信号
for i in range(20):
t = Thread(target=car, args=('熊猫PRO%s' % i,)) # 有二十个车任务线程在等灯
t.start() # 车都在等绿灯才加油门发车。
其他方法
from threading import Thread,current_thread,active_count
current_thread().name
:运行此句代码的线程的名字属性active_count()
:运行此句代码时,本进程中还存在的线程数量