Python 多线程使用
前边介绍了Python的多进程操作,这里记下多线程操作。
创建一个线程
使用threading模块,把函数传入并创建Thread实例,再调用start()开始执行
import time, threading
def f(x):
time.sleep(1)
# threading.current_thread().name 获取线程名字
print('thread %s is running... params %s' % (threading.current_thread().name, x))
if __name__ == '__main__':
threads = []
for i in range(10):
# target 函数名,name线程名字,args传参
t = threading.Thread(target=f, name='workerThreadName', args=(i,))
threads.append(t)
# 开始执行
t.start()
for t in threads:
t.join()
# 这里主线程结束,其他线程也会继续运行
print('thread %s ended.' % threading.current_thread().name)
线程池
直接创建线程的方式比较直接,但存在这样的问题,不好控制线程总数,如果线程启动过多反而会影响整体执行效率。
解决的办法可以使用池化,控制一个总数,使用过的线程再放回池里。
from concurrent.futures import ThreadPoolExecutor
import threading, time
def f(x):
time.sleep(1)
print("thread %s running.. params %s" % (threading.current_thread().name, x))
if __name__ == '__main__':
thread_pool = ThreadPoolExecutor(8)
for i in range(8):
# f执行函数,i传参
thread_pool.submit(f, i)
thread_pool.shutdown()
print("thread %s end" % threading.current_thread().name)
with as
创建一个池,再显示关闭它。这种写法可以使用Python提供的上下文管理器 with as
语法。
# with as 可以免去手动调用 shutdown()
with ThreadPoolExecutor(8) as executor:
for i in range(8):
thread_pool.submit(f, i)
# 这里就已经调用过shutdown()
print("thread %s end" % threading.current_thread().name)
获取任务执行结果
submit返回Future对象,future.result()
获取函数返回值
from concurrent.futures import ThreadPoolExecutor
import threading, time
def f(x):
time.sleep(1)
print("thread %s running.. params %s" % (threading.current_thread().name, x))
return x*x
if __name__ == '__main__':
futures = []
with ThreadPoolExecutor(8) as executor:
for i in range(8):
# submit返回future对象
futures.append(executor.submit(f, i))
# future.result() 获取任务返回值
for future in futures:
# 因为此时这里已经shutdown(),所以可以直接取值
# 否则是个阻塞操作,可选超时时间
print(future.result())
print("thread %s end" % threading.current_thread().name)
线程互斥锁
线程之间操作共享变量,要加锁操作
lock = threading.Lock()
# 获取锁
lock.acquire()
# 释放锁
lock.release()
当然多线程处理还有其他细节,工程经验或者查阅手册等。