UUID、Python线程同步方式
UUID是如何保证唯一性
高可靠,32位16进制数,32*4=128位二进制数,UUID4重复概率1/(2^128),加上时间戳应该好点,UUID1好点。
UUID Version 1:基于时间的UUID
时间戳、随机数和机器MAC地址得到。常用
UUID Version 2:DCE安全的UUID
UUID1的时间戳前4位置换为POSIX的UID或GID
UUID Version 3:基于名字的UUID(MD5)
计算名字和名字空间的MD5散列值得到,相同名字空间中相同名字的UUID重复生成是相同的。
UUID Version 4:随机UUID
随机数。
UUID Version 5:基于名字的UUID(SHA1)
计算名字和名字空间的SHA1值得到。
Python线程同步
昨天面试了一家造汽车的单位,我果然啥都不会via,几分钟就结束了,觉得Python线程同步肯定有用吧,记一下。
临界资源
就是只能有一个线程访问的一块代码,需要进行原子操作的那部分。
1通过锁:threading.Lock
线程共享Num类,访问前需要先获得锁。防止加法出错。另外,RLock
操作可重入,同一个线程内多次acquire(),
程序不会堵塞,但是需要相同的release。
import threading import time class Num: def __init__(self): self.num = 0 self.lock = threading.Lock() def add(self): self.lock.acquire() # 加锁,锁住相应的资源 self.num += 1 self.lock.release() # 解锁,离开该资源 n = Num() class jdThread(threading.Thread): def __init__(self): super().__init__() def run(self): for i in range(10000000): n.add() if __name__ == '__main__': list_thread = [jdThread() for i in range(2)] [t.start() for t in list_thread] [t.join() for t in list_thread] print(n.num)
2.信号量threading.Semaphore
控制同时访问的个数,在执行IO密集型任务时。另外,boundageSamephore用于超过release时的抛出异常。
import threading import time class Num: def __init__(self): self.num = 0 self.sem = threading.Semaphore(value=1) def add(self): self.sem.acquire() # 加锁,锁住相应的资源 print(self.num) time.sleep(0.1) self.sem.release() # 解锁,离开该资源 n = Num() class jdThread(threading.Thread): def __init__(self): super().__init__() def run(self): for i in range(10): n.add() if __name__ == '__main__': list_thread = [jdThread() for i in range(2)] [t.start() for t in list_thread] [t.join() for t in list_thread] print(n.num)
3.条件量threading.Condition()
生产者消费者模式,wait进入等待状态,notify恢复运行
import threading import time class Goods: # 产品类 def __init__(self): self.count = 0 def add(self, num=1): self.count += num def sub(self): if self.count > 0: self.count -= 1 def empty(self): return self.count <= 0 class Producer(threading.Thread): # 生产者类 def __init__(self, condition, goods, sleeptime=1): # sleeptime=1 threading.Thread.__init__(self) self.cond = condition self.goods = goods self.sleeptime = sleeptime def run(self): cond = self.cond goods = self.goods for i in range(1000): time.sleep(self.sleeptime) cond.acquire() goods.add() print("产品数量:", goods.count, "生产者线程") cond.notifyAll() # 唤醒所有等待的线程,唤醒消费者进程 cond.release() class Consumer(threading.Thread): # 消费者类 def __init__(self, condition, goods, sleeptime=2): # sleeptime=2 threading.Thread.__init__(self) self.cond = condition self.goods = goods self.sleeptime = sleeptime def run(self): cond = self.cond goods = self.goods while True: cond.acquire() # 锁住资源 if goods.empty(): # 如无产品则让线程等待 cond.wait() goods.sub() print("产品数量:", goods.count, "消费者线程") cond.release() # 解锁资源 if __name__ == '__main__': g = Goods() c = threading.Condition() list_pro = [Producer(c, g) for _ in range(2)] [p.start() for p in list_pro] list_pro = [Consumer(c, g) for _ in range(5)] [p.start() for p in list_pro]
4.队列queue
线程内的消息队列import queue,进程内的消息队列from multiprocessing import Queue,
import threading import queue import time class jdThread(threading.Thread): def __init__(self, index, queue): threading.Thread.__init__(self) self.index = index self.queue = queue def run(self): while True: time.sleep(1) item = self.queue.get() if item is None: break print("序号:", self.index, "任务", item, "完成") self.queue.task_done() # task_done方法使得未完成的任务数量-1 if __name__ == '__main__': q = queue.Queue(0) for i in range(2): jdThread(i, q).start() # 两个线程同时完成任务 for i in range(10): q.put(i) # put方法使得未完成的任务数量+1
Le vent se lève! . . . il faut tenter de vivre!
Le vent se lève! . . . il faut tenter de vivre!