JasonYeung 2020-03-27
一、锁的作用
锁的作用是:使进程产生同步,确保数据的一致性。
二、线程安全和非线程安全
a = 1 ,两个线程分别给a加一次1,理想结果是 a = 3(线程安全)
如果两个线程同时拿到a=1的状态,分别加上1,那么a = 2(非线程安全)
非线程安全转换为线程安全时,就需要在非线程安全上加上锁
三、代码
# 锁1 (Lock:给一个进程指定一把锁) from multiprocessing import Process import time def l(num): time.sleep(0.2) print("Hello Num: %s" % (num)) time.sleep(0.2) print("Hello Num: %s" % (num)) time.sleep(0.2) print("Hello Num: %s" % (num)) if __name__ == ‘__main__‘: for num in range(50): Process(target=l, args=(num,)).start() 结果: Hello Num: 0 Hello Num: 1 Hello Num: 5 Hello Num: 43 Hello Num: 22 Hello Num: 6 。 。 。 Hello Num: 31 Hello Num: 28 Hello Num: 35 Hello Num: 48 Hello Num: 26 Hello Num: 27 # 结论:没有锁的情况下,子进程拿到数字就会去执行任务,导致打印的数字没有顺序 # 用函数的方式加锁 from multiprocessing import Process, Lock import time def l(lock, num): lock.acquire() # 获得锁 time.sleep(0.02) print("Hello Num: %s" % (num)) time.sleep(0.02) print("Hello Num: %s" % (num)) time.sleep(0.02) print("Hello Num: %s" % (num)) lock.release() # 释放锁 if __name__ == ‘__main__‘: lock = Lock() # 创建一个共享锁实例 for num in range(50): Process(target=l, args=(lock, num)).start() 结果: Hello Num: 15 Hello Num: 15 Hello Num: 15 Hello Num: 13 Hello Num: 13 Hello Num: 13 。 。 。 Hello Num: 37 Hello Num: 37 Hello Num: 37 Hello Num: 23 Hello Num: 23 Hello Num: 23 # 结论:上了锁之后,子进程拿到数字后要等前边的进程出来了,释放了锁它才能进去执行,所有执行结果3个打印是一样的。 # 通过类的方式进行加锁的操作 import time from multiprocessing import Process, Value, Lock class Counter(object): def __init__(self, initval=0): self.val = Value(‘i‘, initval) # 全局共享变量,i 是指整型,d 是指双精度小鼠 self.lock = Lock() # 初始化了一个锁 def increment(self): # 在加锁的情况下,进行数字累加1 with self.lock: # 这个是加锁操作 self.val.value += 1 # 共享变量自加1 # print("increment one time!",self.value()) # 加此句死锁 def value(self): # 读取的时候也是加锁的 with self.lock: # 这个是加锁操作,和上面那个的区别是:这个是加锁和释放锁都是自动完成的。 return self.val.value def func(counter): for i in range(50): time.sleep(0.01) counter.increment() if __name__ == ‘__main__‘: counter = Counter(0) procs = [Process(target=func, args=(counter,)) for i in range(10)] for p in procs: p.start() for p in procs: p.join() print(counter.value()) 结果: 500
# 锁2:(Semaphore:给多个进程上多把锁,就是限制几个进程可以同时并发) import multiprocessing import time def worker(s, i): s.acquire() # 加锁 print(multiprocessing.current_process().name + " acquire") time.sleep(i) print(multiprocessing.current_process().name + " release") s.release() # 释放锁 if __name__ == "__main__": # 设置限制最多3个进程同时访问共享资源 s = multiprocessing.Semaphore(3) for i in range(5): p = multiprocessing.Process(target=worker, args=(s, i * 2)) p.start() 结果: Process-1 acquire Process-1 release Process-3 acquire Process-2 acquire Process-2 release Process-4 acquire Process-3 release Process-5 acquire Process-4 release Process-5 release