(1)线程之间虽然数据共享,但是多个线程同时修改同一份数据,依然会造成数据的不准确,因此,也需要加
上线程锁Lock,用法和进程锁一样,只不过是从threading里面导包
(2)不要因为逻辑问题让上锁分成两次.导致死锁,递归锁用于解决死锁,但只是一种应急的处理办法,关键
时刻可以防止服务器崩溃,递归锁:RLock:只要第一个进程拿到锁,该进程往下的锁全部打开,等他
走完了,再放下一个进程进来
(3)从语法上说,锁是允许互相嵌套的,但是不要使用;
上一次锁,就对应解开一次,形成互斥锁
吃面和拿筷子是同时的,不要因为逻辑问题让锁分别上,容易造成死锁.
(4)线程中的信号量Semaphore
进程而言:
信号量是配合Process使用,可以限制并发的进程数
在有了进程池之后,可以取代如上做法
线程而言:
信号量是配合Thread使用的,可以限制并发的线程数
线程池可以取代如上用法
from threading import Thread, Lock
import time
mylock = Lock()
def eat1(name):
mylock.acquire()
print("%s拿到筷子" % (name))
print("%s吃到面条" % (name))
time.sleep(0.5)
print("%s放下筷子" % (name))
print("%s放下面条" % (name))
mylock.release()
def eat2(name):
mylock.acquire()
print("%s拿到筷子" % (name))
print("%s吃到面条" % (name))
time.sleep(0.5)
print("%s放下筷子" % (name))
print("%s放下面条" % (name))
mylock.release()
if __name__ == "__main__":
name_list = ["张楠", "定海呀"]
name_list2 = ["晨露中", "周金波"]
for name in name_list:
Thread(target=eat1, args=(name,)).start()
for name in name_list2:
Thread(target=eat2, args=(name,)).start()