多线程有两个模块:_thread(低级模块)和threading(高级模块),大多时候使用threading模块。
启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行。
import time,threading
#新线程
def sss():
print('gogogogogo')
n=0
while n<=5:
n=n+1
print('%s--%s' %(threading.current_thread().name,n))
time.sleep(1)
print('end')
#与进程对比,没有if __name__='__main__':
print('first time')
#注意threading模块的用法
t=threading.Thread(target=sss,name='Loopthread')
t.start()
t.join()
多进程和多线程的最大的区别在于,在多进程中同一个变量在每个进程中都有一个拷贝,互补影响,而在多线程中所有变量共享。多线程同时改变一个变量,会把内容改乱。
threading.Lock()
使用 try…finally 来确保锁一定会被释放
balance = 0
lock = threading.Lock()
def run_thread(n):
for i in range(100000):
# 先要获取锁:
lock.acquire()
try:
# 放心地改吧:
change_it(n)
finally:
# 改完了一定要释放锁:
lock.release()
threading.local()
import threading
# 创建全局ThreadLocal对象:
local_school = threading.local()
def process_student():
# 获取当前线程关联的student:
std = local_school.student
print('Hello, %s (in %s)' % (std, threading.current_thread().name))
def process_thread(name):
# 绑定ThreadLocal的student:
local_school.student = name
process_student()
t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A')
t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()
全局变量local_school就是一个ThreadLocal对象,每个Thread对它都可以读写student属性,但互不影响。你可以把local_school看成全局变量,但每个属性如local_school.student都是线程的局部变量,可以任意读写而互不干扰,也不用管理锁的问题,ThreadLocal内部会处理。
可以理解为全局变量local_school是一个dict,不但可以用local_school.student,还可以绑定其他变量,如local_school.teacher等等。
ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源。
分布式进程
优先选多进程,多进程更稳定,而且可以分布到多台机器上去,多线程最多可以分不到一台机器的多个CPU上。
multiprocessing模块中的managers子模块支持把多进程分布到多台机器上去。一个服务进程作为调度者。