python多线程threading
目录
threading介绍与简单使用
join功能
queue功能
lock锁
threading介绍与简单使用
threading介绍:
threading模块 threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法: threading.currentThread(): 返回当前的线程变量。 threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。 除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法: run(): 用以表示线程活动的方法。 start():启动线程活动。 join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。 isAlive(): 返回线程是否活动的。 getName(): 返回线程名。 setName(): 设置线程名。
程序示例:import threading
import threading
def thread_job():
print("this is an added Thread ,number is %s" %threading.currentThread())
def main():
added_thread = threading.Thread(target=thread_job) # 定义一个新的线程,指定一个任务给target
added_thread.start() # 开启线程
print(threading.activeCount())
print(threading.enumerate())
print(threading.currentThread())
if __name__ =='__main__':
main()
程序运行结果:
第一个输出是当前线程,这个是我们开启的线程
第二个输出的是在正在运行的线程的数量
第三个输出返回一个包含正在运行的线程的list,包含主线程和开启的线程
第四个输出是当前线程,最后只剩下主线程
join功能
join功能介绍:
join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
当我们有一个程序功能必须等到开启的线程执行完以后,才能运行主线程,就可以使用这个功能。
不加join的情况,这种情况下,以下例程序看来,主线程运行更快,我们看看结果
程序示例1:
import threading
import time
def thread_job():
print("T1 start")
for i in range(10):
time.sleep(0.1)
print("T1 finish")
def main():
added_thread = threading.Thread(target=thread_job,name = 'T1') #定义一个新的线程,指定一个任务给target
added_thread.start() #开启线程
print("all done")
if__name__=='__main__':
main()
程序运行结果:
加join的情况,等待我们开启的线程执行完以后才能运行主线程。
程序示例2:
import threading
import time
def thread_job():
print("T1 start")
for i in range(10):
time.sleep(0.1)
print("T1 finish")
def main():
added_thread = threading.Thread(target=thread_job,name = 'T1') #定义一个新的线程,指定一个任务给target
added_thread.start() #开启线程
added_thread.join()
print("all done")
if __name__ == '__main__':
main()
程序运行结果:
queue功能
queue功能:
线程优先级队列( Queue) Python 的 Queue 模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列 PriorityQueue。 这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现线程间的同步。 Queue 模块中的常用方法: Queue.qsize() 返回队列的大小 Queue.empty() 如果队列为空,返回True,反之False Queue.full() 如果队列满了,返回True,反之False Queue.full 与 maxsize 大小对应 Queue.get([block[, timeout]])获取队列,timeout等待时间 Queue.get_nowait() 相当Queue.get(False) Queue.put(item) 写入队列,timeout等待时间 Queue.put_nowait(item) 相当Queue.put(item, False) Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号 Queue.join() 实际上意味着等到队列为空,再执行别的操作
下面只演示了在多线程中怎么返回线程中的运行结果,因为不能使用return返回! 使用Queue.get()和Queue.put()方法
程序示例:
import threading
from queue import Queue
def job(l,q):
for i in range(len(l)):
l[i] = l[i] + 1 # 对列表里每一个值加一
q.put(l) # 把计算的结果保存到queue
def main():
q = Queue() # 使用queue存放返回值
threads = [] # 创建进程列表
data = [[1, 2], [3, 4], [4, 5], [5, 6]]
# 创建四个进程并启动添加到进程列表里面
for i in range(4):
t = threading.Thread(target=job, args=(data[i], q))
t.start()
threads.append(t)
# 把所有线程都加到主线程中
for thread in threads:
thread.join()
# 创建存放结果的列表
results = []
# 把结果保存到results列表中
for _ in range(4):
results.append(q.get())
print(results)
if __name__ =='__main__':
main()
程序运行结果:
比较多线程和不使用多线程的运行速度
我们知道python中实现多线程其实是把正在运行的线程锁住,这时候其他线程就不会运行,就是在同一时间里只有一个线程在运行,在不断地切换线程中就可以实现多线程。
下面我使用多线程和不使用线程,来做同样的运算工作,看谁运行的更快。
import threading
from queue import Queue
import time
def job(l,q):
for i in range(len(l)):
l[i] = l[i] + 1 # 对列表里每一个值加一
q.put(l) # 把计算的结果保存到queue
def normal(l):
results = []
for i in range(len(l)):
l[i] = l[i] + 1
results.append(l[i])
return results
def main(list):
q = Queue() # 使用queue存放返回值
threads = [] # 创建进程列表
# 创建四个进程并启动添加到进程列表里面
for i in range(4):
t = threading.Thread(target=job, args=(list[i], q))
t.start()
threads.append(t)
# 把所有线程都加到主线程中
for thread in threads:
thread.join()
# 创建存放结果的列表
results = []
# 把结果保存到results列表中
for _ in range(4):
results.append(q.get())
print(results)
if __name__ =='__main__':
data1 = [[1, 2], [3, 4], [4, 5], [5, 6]]
data2 = [[1, 2], [3, 4], [4, 5], [5, 6]]
start1_time =time.time()
main(data1)
print(time.time()-start1_time)
start2_time = time.time()
result = []
for i in range(len(data2)):
result.append(normal(data2[i]))
print(result)
print(time.time()-start2_time)
运行结果:
在pycham和网上的在线编译器上都运行过,大致上来多线程运行的速度要快不少
lock锁
lock锁:
当多个线程同时运行,比如一个线程接收信息,另一个线程处理信息,功能就是需要接收信息的线程执行完,才能执行另一处理信息的线程,就可以使用这个功能。
lock.acquire() 锁住
lock.release() 解锁
程序示例:
import threading
def job1():
global A,lock
lock.acquire()
for i in range(10):
A += 1
print('job1', A)
lock.release()
def job2():
global A,lock
lock.acquire()
for i in range(10):
A += 10
print('job2', A)
lock.release()
if __name__ == '__main__':
A = 0
lock = threading.Lock()
t1 = threading.Thread(target=job1)
t2 = threading.Thread(target=job2)
t1.start()
t2.start()
t1.join()
t2.join()
程序运行结果: