Python 线程同步

– Start

点击此处观看本系列配套视频。


当多个线程对同一个对象进行读写操作时将引发并发问题, 学过数据库的人都知道并发将导致脏读和丢失更新等错误, 本文将介绍 Python 是如何解决并发问题的.

Lock 类

from threading import Thread
from threading import Lock


# 定义账户类
class Account:
    def __init__(self, debit):
        self.debit = debit
        self.lock = Lock()

    def increase(self, amount):
        self.lock.acquire()
        try:
            self.debit += amount
        finally:
            self.lock.release()


account = Account(0)


# 启动两个线程同时转账
def transfer():
    for i in range(1000000):
        account.increase(1)


t1 = Thread(target=transfer)
t2 = Thread(target=transfer)

t1.start()
t2.start()

# 等待 t1 和 t2 结束,打印结果
t1.join()
t2.join()
print(account.debit)

with 语句

    def increase(self, amount):
        with self.lock:
            self.debit += amount

RLock 类

from threading import Thread
from threading import RLock


# 定义账户类
class Account:
    def __init__(self, debit):
        self.debit = debit
        self.lock = RLock()
        self.credit = 0

    def increase(self, amount):
        with self.lock:
            self.decrease_credit(amount)
            self.debit += amount

    def decrease_credit(self, amount):
        with self.lock:
            self.credit -= amount


account = Account(0)


# 启动两个线程同时转账
def transfer():
    for i in range(1000000):
        account.increase(1)


t1 = Thread(target=transfer)
t2 = Thread(target=transfer)

t1.start()
t2.start()

# 等待 t1 和 t2 结束,打印结果
t1.join()
t2.join()
print(account.debit)

BoundedSemaphore 类

import threading
from threading import Thread
from threading import BoundedSemaphore
from datetime import datetime

# 定义服务类
class Service:
    def __init__(self):
        # 同时提供 3 个服务
        self.available = BoundedSemaphore(value=3)

    def serve(self):
        with self.available:
            print(f'{datetime.now()} -- serving {threading.current_thread().getName()}')


# 启动 10 个线程
service = Service()
for i in range(10):
    Thread(target=lambda service: service.serve(), args=(service, )).start()

Event 类

import threading
from threading import Thread
from threading import Event
from datetime import datetime

event = Event()


def my_task():
    event.wait() # 等待
    print(f'{datetime.now()} -- {threading.current_thread().getName()} is running.   ')


# 启动 10 个线程
for i in range(10):
    Thread(target=my_task).start()


print('Starting all threads')
event.set() # 所有等待线程开始执行

Barrier 类

import threading
import time
from threading import Thread
from threading import Barrier
from datetime import datetime

# 当调用 3 次 wait
barrier = Barrier(3)


def init_db():
    print('init DB starting')
    time.sleep(2)
    print('init DB done')
    barrier.wait()


def init_cache():
    print('init Cache starting')
    time.sleep(2)
    print('init Cache done')
    barrier.wait()


# 启动两个线程分别初始化 db 和 cache
Thread(target=init_db).start()
Thread(target=init_cache).start()


print('Service is not ready, waiting for init db and cache')
barrier.wait()
print('Service is ready now')

– 更多参见:Python 精萃
– 声 明:转载请注明出处
– Last Updated on 2018-10-09
– Written by ShangBo on 2018-10-06
– End

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值