UUID、Python线程同步方式

2021-11-30 19:55:59 浏览数 (1)

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。

代码语言:javascript复制
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时的抛出异常。

代码语言:javascript复制
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恢复运行

代码语言:javascript复制
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,

代码语言:javascript复制
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

0 人点赞