线程锁(互斥锁Mutex)
一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据,此时,如果2个线程同时要修改同一份数据,会出现什么状况?就会可能存在同时取出了一个数据进行操作,然后存回去,这样就会丢失一次操作。所以用锁,在修改之前锁上数据,修改之后再释放锁,期间别人不能使用这个数据。
例子:
import threading
num = 0 #全局变量
lock = threading.Lock() #生成全局锁
def add():
global num # 在每个线程中都获取这个全局变量
lock.acquire() # 修改数据前加锁
num += 1 # 对此公共变量进行+1操作
lock.release() # 修改后释放
thread_list = []
for i in range(100):
t = threading.Thread(target=add)
t.start()
thread_list.append(t)
for t in thread_list: # 等待所有线程执行完毕
t.join()
print('final num:', num)
线程锁只允许同一时刻一个线程修改变量,如果要在同一时刻允许多个线程修改变量,用信号量。
信号量Semaphore
线程锁同时只允许一个线程更改数据,而信号量是同时允许一定数量的线程更改数据 。
import threading, time
#信号量
def run(n):
semaphore.acquire()
time.sleep(1) #控制每个线程1秒运行时间
print("run the thread: %s\n" % n)
semaphore.release()
semaphore = threading.BoundedSemaphore(3) # 最多允许5个线程同时运行
for i in range(20):
t = threading.Thread(target=run, args=(i,))
t.start()
while threading.active_count() != 1: #还有线程在活动就不结束
pass
else:
print('----all threads done---')