python中多线程同步实现

import threading
import time

# python 实现线程同步:Event、(R)Lock、semaphore、barricade、condition

# Event 使用:e.set() e.clear() e.is_set() e.wait()
def event_usage():  # 主要就set设置event为True,clear变false,wait 用于等待True,is_set来判断是否为True
    l = []
    e = threading.Event()

    def pro():
        while True:
            l.append(1)
            print('adding ', l)
            time.sleep(1)
            if len(l) == 5:
                print(l)
                e.set()  # set之后Event 为True,可以让另一个线程使用

    def con():
        while True:
            e.wait()  # 先等待Event 变成True
            print('grab all ~~')
            l.clear()
            e.clear()  # 完成之后用clear再把event 变成False ,继续等待adding

    p = threading.Thread(target=pro)
    c = threading.Thread(target=con)
    p.start()
    c.start()


# Lock的使用: acquire 默认blocking=True,timeout=-1 上锁,不能用 。 使用release 释放就能使用
# 注意 ,加锁就要解锁,但是有些程序中断导致没有解锁,因此最好使用try finally的语句保证 解锁,避免死锁
# Rlock 可重入锁,在同一线程内可以反复获得锁,其他线程想使用会阻塞。 释放锁的时候要做相应多次的release别的线程才能使用。

def lock_usage():
    l = []
    lock = threading.Lock()

    def one():
        while True:
            time.sleep(1)
            lock.acquire()
            l.append(1)
            print('adding completed,release')
            lock.release()

    def two():
        while True:
            time.sleep(0.1)
            if len(l) % 6 == 0:
                lock.acquire()
                print('time to sleep 5secs')
                time.sleep(5)
                lock.release()

    t1 = threading.Thread(target=one)
    t2 = threading.Thread(target=one)
    t3 = threading.Thread(target=two)
    t1.start()
    t2.start()
    t3.start()


# condition  wait 等待通知, notifyall 通知所有等待的线程
class cond:
    def __init__(self):
        self.l = []
        self.cond = threading.Condition()

    def pro(self):
        with self.cond:
            print('wait 3 s')
            time.sleep(3)
            self.cond.notify_all()
            time.sleep(3)
            print('t1 done')

    def con(self):
        with self.cond:
            self.cond.wait()
            print('go go go')
            time.sleep(1)
            print('t2 done')

    def start(self):
        t1 = threading.Thread(target=self.pro)
        t2 = threading.Thread(target=self.con)
        t2.start()  # 必须t2先开始 ,with 获得锁,然后wait 解开锁并加入等待池,然后t1的with 再获得锁,直到notifyall t2继续运行,
        t1.start()


# barrier : barrier(3#等几个线程就打破屏障)  wait(线程等待屏障打破) : 所有线程等待barrier打破 。 abort()打破屏障,等待中的线程会抛broken异常 。reset()重设屏障
def barrier_usage():
    b = threading.Barrier(2)  # 等待线程达到两个就打破barrier

    def p():
        b.wait()
        print('gogogo')

    t1 = threading.Thread(target=p)
    t2 = threading.Thread(target=p)

    t1.start()
    t2.start()


# semaphore  用法和lock类似,但是acquire 计数-1 ,release计数+1,计数为0 时候就阻塞线程,负数时候报错,
def semaphore_usage():
    t = threading.Semaphore()

    def a():
        t.acquire()
        print('111')

    def b():
        t.acquire()  # 执行后 计数为0 ,别的线程被阻塞
        print('222')
        time.sleep(1)
        t.release()  # 计数回正后 不再阻塞可以打印a

    t1 = threading.Thread(target=a)
    t2 = threading.Thread(target=b)
    t2.start()
    t1.start()


semaphore_usage()

你可能感兴趣的:(数据结构与算法)