加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

python lock, semaphore, event达成线程同步

发布时间:2021-11-15 11:36:03 所属栏目:PHP教程 来源:互联网
导读:lock 机制不管你是java, C#, 还是Python都是常用的线程同步机制, 相比较C# 的锁机制, python的加锁显得比较简单, 直接调用threading 标准库的lock 就可以了. python 的 lock类有两个函数, 分别是acquire 函数以及 release 函数, 前者起到锁定的作用, 将状态

 lock 机制不管你是java, C#, 还是Python都是常用的线程同步机制, 相比较C# 的锁机制, python的加锁显得比较简单, 直接调用threading 标准库的lock 就可以了. python 的 lock类有两个函数, 分别是acquire 函数以及 release 函数, 前者起到锁定的作用, 将状态设置为锁定状态, 后者则是解锁, 将状态设置为未锁定状态. 我们看看代码:
 
# python 多线程同步  lock
import threading
from time import sleep
 
 
num = 0
lock = threading.Lock()
 
 
def func(st):
    global num
    print(threading.currentThread().getName() + ' try to acquire the lock')
    if lock.acquire():  # 将状态修改为locked
        print(threading.currentThread().getName() + ' acquire the lock.')
        print(threading.currentThread().getName() + " :%s" % str(num))
        num += 1
        # sleep(st)
        print(threading.currentThread().getName() + ' release the lock.')
        lock.release()  # 将状态修改为unlocked
 
 
t1 = threading.Thread(target=func, args=(8,))
t2 = threading.Thread(target=func, args=(4,))
t3 = threading.Thread(target=func, args=(2,))
t1.start()
t2.start()
t3.start()
我们开了三个线程去调用同一个func 函数, 由于线程的不确定性, 如果没有加锁, 此时运行的话就会很混乱, 三个线程去执行同一个函数, 如果涉及到了变量的数据变化更是坑!因此我们加了锁, 确保数据的正确性, 函数执行的顺序性!
 
semaphore 信号量机制在python 里面也很简单就能够实现线程的同步。如果对操作系统有一定的了解, 那么对操作系统的PV原语操作应该有印象, 信号量其实就是基于这个机制的.semaphore 类是threading 模块下的一个类, 主要两个函数: acquire 函数, release 函数这和lock 类的函数是一样的, 只不过功能不一样, semaphore 机制的acquire 函数的参数允许你自己设置最大的并发量, 就是说允许多少个线程来操作同一个函数或是变量, 同时执行一次就会递减一次, release 函数则是递增, 如果计数到了0, 则阻塞起线程, 不再允许线程访问该方法或是变量.
 
# python 多线程同步   semaphore
import threading
 
 
# 初始化信号量数量...当调用acquire 将数量置为 0, 将阻塞线程等待其他线程调用release() 函数
semaphore = threading.Semaphore(2)
 
 
def func():
    if semaphore.acquire():
        for i in range(5):
            print(threading.currentThread().getName() + ' get semaphore')
        semaphore.release()
        print(threading.currentThread().getName() + ' release semaphore')
 
 
if __name__ == '__main__':
    for i in range(4):
        t1 = threading.Thread(target=func)
        t1.start()
我们一次允许两个线程同时执行函数, 这可以从截图看出来:
 
 
event 机制不仅能够实现线程间的通信, 也是实现线程同步的一个好方法。事件是线程之间通信的最简单的机制之一, 一个线程指示一个事件和其他线程等待它.
event.py 是threading 模块下的一个类, 相比较前面两个机制, 这个类提供了四个方法, 分别是 is_set() 函数, set() 函数, clear() 函数, wait() 函数.
is_set判断事件管理标志是不是为true, 只有为true时, 才会返回
set 将标志设置为true
clear 将标志设置为flase
wait 等到标志为true时, 才会停止阻塞线程
 
import logging
import threading
import time
 
 
# 打印线程名以及日志信息
logging.basicConfig(level=logging.DEBUG, format="(%(threadName)-10s : %(message)s", )
 
 
def wait_for_event_timeout(e, t):
    """Wait t seconds and then timeout"""
    while not e.isSet():
        logging.debug("wait_for_event_timeout starting")
        event_is_set = e.wait(t)  # 阻塞, 等待设置为true
        logging.debug("event set: %s" % event_is_set)
        if event_is_set:
            logging.debug("processing event")
        else:
            logging.debug("doing other work")
 
 
e = threading.Event()  # 初始化为false
t2 = threading.Thread(name="nonblock", target=wait_for_event_timeout, args=(e, 2))
t2.start()
logging.debug("Waiting before calling Event.set()")
# time.sleep(7)
e.set()  # 唤醒线程, 同时将event 设置为true
logging.debug("Event is set")

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读