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")

python lock, semaphore, event实现线程同步的更多相关文章

  1. python类库32[多进程同步Lock+Semaphore+Event]

    python类库32[多进程同步Lock+Semaphore+Event]   同步的方法基本与多线程相同. 1) Lock 当多个进程需要访问共享资源的时候,Lock可以用来避免访问的冲突. imp ...

  2. Python并行编程(三):线程同步之Lock

    1.基础概念 当两个或以上对共享内存操作的并发线程中,如果有一个改变数据,又没有同步机制的条件下,就会产生竞争条件,可能会导致执行无效代码.bug等异常行为. 竞争条件最简单的解决方法是使用锁.锁的操 ...

  3. Python多线程(2)——线程同步机制

    本文介绍Python中的线程同步对象,主要涉及 thread 和 threading 模块. threading 模块提供的线程同步原语包括:Lock.RLock.Condition.Event.Se ...

  4. Python并行编程(五):线程同步之信号量

    1.基本概念 信号量是由操作系统管理的一种抽象数据类型,用于在多线程中同步对共享资源的使用.本质上说,信号量是一个内部数据,用于标明当前的共享资源可以有多少并发读取. 同样在threading中,信号 ...

  5. [b0034] python 归纳 (十九)_线程同步_条件变量

    代码: # -*- coding: utf-8 -*- """ 学习线程同步,使用条件变量 逻辑: 生产消费者模型 一个有3个大小的产品库,一个生产者负责生产,一个消费者 ...

  6. [b0031] python 归纳 (十六)_线程同步_锁

    # -*- coding: utf-8 -*- """ 学习 多线程同步 使用锁 threading.Lock() 逻辑: 2 个线程,操作同一个整型变量,一个加法,另外 ...

  7. 线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯

    1.Lock相关知识介绍 好比我同时种了几块地的麦子,然后就等待收割.收割时,则是哪块先熟了,先收割哪块. 下面举一个面试题的例子来引出Lock缓存读写锁的案例,一个load()和get()方法返回值 ...

  8. Python并行编程(七):线程同步之事件

    1.基本概念 事件是线程之间用于通讯的对象.有的线程等待信号,有的线程发出信号.基本上事件对象都会维护一个内部变量,可以通过set方法设置为true,也可以通过clear方法设置为false.wait ...

  9. Python并行编程(四):线程同步之RLock

    1.基本概念 如果想让只有拿到锁的线程才能释放该锁,那么应该使用RLock()对象.当需要在类外面保证线程安全,又要在类内使用同样方法的时候RLock()就很使用. RLock叫做Reentrant ...

随机推荐

  1. DFS(深度优先)算法编程实践

    DFS定义 DFS(Depth-First-Search)深度优先搜索算法,是搜索算法的一种.是一种在开发爬虫早期使用较多的方法.它的目的是要达到被搜索结构的叶结点 . 特点 每次深度优先搜索的结果必 ...

  2. 安装解压版本的MySQL,安装过程中的常见命令,检查windows系统错误日志的方式来检查MySQL启动错误,关于Fatal error: Can't open and lock privilege

     以端口 port = 3306 # 设置mysql的安装目录 basedir=D://Installed//mysql-5.6.26-winx64//mysql-5.6.26-winx64 # ...

  3. 开源项目——小Q聊天机器人V1.3

    小Q聊天机器人V1.0 http://blog.csdn.net/baiyuliang2013/article/details/51386281 小Q聊天机器人V1.1 http://blog.csd ...

  4. Android开发-Listview中显示不同的视图布局

    1. 使用场景 在重写ListView的BaseAdapter时,我们常常在getView()方法中复用convertView,以提高性能.convertView在Item为单一的同种类型布局时,能够 ...

  5. 用SpriteBuilder简化"耕牛遍地走"的动画效果(三)

    接下来的代码和原文差不多,建立一个数组用来存放动画帧,然后用数组来初始化一个CCAnimation动画对象.接着将牛放在屏幕中心,然后运行动画: NSMutableArray *walkAnimFra ...

  6. Linux Debugging(三): C++函数调用的参数传递方法总结(通过gdb+反汇编)

    上一篇文章<Linux Debugging:使用反汇编理解C++程序函数调用栈>没想到能得到那么多人的喜爱,因为那篇文章是以32位的C++普通函数(非类成员函数)为例子写的,因此只是一个特 ...

  7. Oracle Instance

    以前也学习过oracle 逻辑结构的知识,但用的不多好多都是有点概念,最近做到一个跨instance工作流,所有抽点时间温习了一下相关知识,把网上看到的感觉讲的还比较明了,全面的文章汇总一下 inst ...

  8. 海量数据挖掘MMDS week2: 局部敏感哈希Locality-Sensitive Hashing, LSH

    http://blog.csdn.net/pipisorry/article/details/48858661 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...

  9. Github搭建属于自己的开源项目-androd学习之旅(72)

    Github是一个基于的git的版本控制工具,分为私人代码管理和开源代码管理,下面我们简单的介绍一下 首先登陆官网https://github.com 完成注册,随后首页会有四个模块,第一个是安装的指 ...

  10. 学习pthreads,管理线程的栈

    进程的地址空间分成代码段,静态数据段,堆和栈段.线程栈的位置和大小是从它所属的进程的栈中切分出来的.每个栈必须足够大,以容纳所有对等线程的函数的执行以及它们将会调用的例程链.或许你会问为什么要进行线程 ...