同步锁 php,python线程中同步锁详解

这篇文章主要为大家详细介绍了python线程中同步锁的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lock Rlock Semaphore Event Condition 用来保证线程之间的同步,后者保证访问共享变量的互斥问题

Lock & RLock:互斥锁 用来保证多线程访问共享变量的问题

Semaphore对象:Lock互斥锁的加强版,可以被多个线程同时拥有,而Lock只能被某一个线程同时拥有。

Event对象: 它是线程间通信的方式,相当于信号,一个线程可以给另外一个线程发送信号后让其执行操作。

Condition对象:其可以在某些事件触发或者达到特定的条件后才处理数据

1、Lock(互斥锁)

请求锁定 — 进入锁定池等待 — 获取锁 — 已锁定 — 释放锁

Lock(指令锁)是可用的最低级的同步指令。Lock处于锁定状态时,不被特定的线程拥有。Lock包含两种状态——锁定和非锁定,以及两个基本的方法。

可以认为Lock有一个锁定池,当线程请求锁定时,将线程至于池中,直到获得锁定后出池。池中的线程处于状态图中的同步阻塞状态。

构造方法:

Lock()

实例方法:

acquire([timeout]): 使线程进入同步阻塞状态,尝试获得锁定。

release(): 释放锁。使用前线程必须已获得锁定,否则将抛出异常。

if mutex.acquire():

counter += 1

print "I am %s, set counter:%s" % (self.name, counter)

mutex.release()

2、RLock(可重入锁)

RLock(可重入锁)是一个可以被同一个线程请求多次的同步指令。RLock使用了“拥有的线程”和“递归等级”的概念,处于锁定状态时,RLock被某个线程拥有。拥有RLock的线程可以再次调用acquire(),释放锁时需要调用release()相同次数。

可以认为RLock包含一个锁定池和一个初始值为0的计数器,每次成功调用 acquire()/release(),计数器将+1/-1,为0时锁处于未锁定状态。

构造方法:

RLock()

实例方法:

acquire([timeout])/release(): 跟Lock差不多。

3、Semaphore(共享对象访问)

咱们再聊聊Semaphore ,说实话Semaphore是我最晚使用的同步锁,以前类似的实现,是我用Rlock实现的,相对来说有些绕,毕竟Rlock 是需要成对的锁定和开锁的》。。。

Semaphore管理一个内置的计数器,

每当调用acquire()时内置计数器-1;

调用release() 时内置计数器+1;

计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。

直接上代码,我们把semaphore控制为3,也就是说,同时有3个线程可以用这个锁,剩下的线程也之只能是阻塞等待了…

#coding:utf-8

#blog xiaorui.cc

import time

import threading

semaphore = threading.Semaphore(3)

def func():

if semaphore.acquire():

for i in range(3):

time.sleep(1)

print (threading.currentThread().getName() + '获取锁')

semaphore.release()

print (threading.currentThread().getName() + ' 释放锁')

for i in range(5):

t1 = threading.Thread(target=func)

t1.start()

4、Event(线程间通信)

Event内部包含了一个标志位,初始的时候为false。

可以使用使用set()来将其设置为true;

或者使用clear()将其从新设置为false;

可以使用is_set()来检查标志位的状态;

另一个最重要的函数就是wait(timeout=None),用来阻塞当前线程,直到event的内部标志位被设置为true或者timeout超时。如果内部标志位为true则wait()函数理解返回。

import threading

import time

class MyThread(threading.Thread):

def __init__(self, signal):

threading.Thread.__init__(self)

self.singal = signal

def run(self):

print "I am %s,I will sleep ..."%self.name

self.singal.wait()

print "I am %s, I awake..." %self.name

if __name__ == "__main__":

singal = threading.Event()

for t in range(0, 3):

thread = MyThread(singal)

thread.start()

print "main thread sleep 3 seconds... "

time.sleep(3)

singal.set()

5、Condition(线程同步)

可以把Condition理解为一把高级的琐,它提供了比Lock, RLock更高级的功能,允许我们能够控制复杂的线程同步问题。threadiong.Condition在内部维护一个琐对象(默认是RLock),可以在创建Condigtion对象的时候把琐对象作为参数传入。Condition也提供了acquire, release方法,其含义与琐的acquire, release方法一致,其实它只是简单的调用内部琐对象的对应的方法而已。Condition还提供了如下方法(特别要注意:这些方法只有在占用琐(acquire)之后才能调用,否则将会报RuntimeError异常。):

Condition.wait([timeout]):

wait方法释放内部所占用的琐,同时线程被挂起,直至接收到通知被唤醒或超时(如果提供了timeout参数的话)。当线程被唤醒并重新占有琐的时候,程序才会继续执行下去。

Condition.notify():

唤醒一个挂起的线程(如果存在挂起的线程)。注意:notify()方法不会释放所占用的琐。

Condition.notify_all()

Condition.notifyAll()

唤醒所有挂起的线程(如果存在挂起的线程)。注意:这些方法不会释放所占用的琐。

对于Condition有个例子,大家可以观摩下。

from threading import Thread, Condition

import time

import random

queue = []

MAX_NUM = 10

condition = Condition()

class ProducerThread(Thread):

def run(self):

nums = range(5)

global queue

while True:

condition.acquire()

if len(queue) == MAX_NUM:

print "Queue full, producer is waiting"

condition.wait()

print "Space in queue, Consumer notified the producer"

num = random.choice(nums)

queue.append(num)

print "Produced", num

condition.notify()

condition.release()

time.sleep(random.random())

class ConsumerThread(Thread):

def run(self):

global queue

while True:

condition.acquire()

if not queue:

print "Nothing in queue, consumer is waiting"

condition.wait()

print "Producer added something to queue and notified the consumer"

num = queue.pop(0)

print "Consumed", num

condition.notify()

condition.release()

time.sleep(random.random())

ProducerThread().start()

ConsumerThread().start()

相关推荐:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/496314.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

移动平均线分析法

移动平均线分析法是由道琼斯股价理论演变出来的一种股价趋势分析方法。其基本思想是消除股价随机波动的影响,以寻求股价波动的趋势。主要特点:1、追踪趋势:MA能够表示股价波动的趋势,并追踪这个趋势不轻易改变。2、滞后性&#xf…

Spring Data JPA 从入门到精通~Auditing及其事件详解

Auditing 及其事件详解 Auditing 翻译过来是审计和审核,Spring 的优秀之处在于帮我们想到了很多繁琐事情的解决方案,我们在实际的业务系统中,针对一张表的操作大部分是需要记录谁什么时间创建的,谁什么时间修改的,并且…

未来城市的无人机送货系统是怎样的?

来源: 资本实验室 作者:李鑫Siri通过移动应用下了一盒巴克拉拉面膜的订单,电商平台收到信息,发指令给最近的送货驳船。驳船上的无人机获取货物包裹后直接飞向Siri家。在不到8分钟的飞行后,无人机来到位于12层的Siri家…

Vim自动补全神器:YouCompleteMe

From:http://www.jianshu.com/p/d908ce81017a github 地址:https://github.com/Valloric/YouCompleteMe YouCompleteMe is a fast, as-you-type, fuzzy-search code completion engine for Vim. 参考: https://github.com/Valloric/YouCom…

故障树分析法MATLAB,故障树分析(FTA)方法及其基于VC的软件设计的研究

故障树分析法(FTA)是一种评价复杂系统可靠性与安全性的重要方法。经过近四十年的发展,FTA技术已经有相对成熟的理论,但是在FTA的组合爆炸困难(计算量随故障树规模指数增长)、相关底事件的FTA 等方面还有待于进一步的研究。而且随着系统复杂性的加大,系统所含部件愈来愈多,研究系…

Windows 7硬盘安装方法大全

Windows 7硬盘安装方法大全,共整理出四种方法该Windows 7硬盘安装方法大全介绍了Windows 7下安装高版本的Windows 7,Vista下硬盘安装Windows 7,xp下硬盘安装Windows7等方法! 一、 windows 7 系统下全新安装高版Windows7&#xff1…

对比 | 欧洲、美国、中国智慧城市的不同实践路径

来源:《上海城市规划》2018年第1期《欧美智慧城市最新实践与参考》作者:刘杨 龚烁 刘晋媛随着ICT、大数据、物联网等各类新兴技术的不断发展,智慧城市的运营和实践也不断趋于成熟。通过整理欧美各大典型智慧城市的最新实践案例,总…

C++ 使用 TinyXml 解析 XML 文件

知乎 C解析xml有什么好用的轮子? :https://www.zhihu.com/question/32046606 TinyXML-2 的 github地址和帮助文档:https://github.com/leethomason/tinyxml2 tinyxml 下载地址:https://sourceforge.net/projects/tinyxml/ *Please Note*…

java1.8.0,jdk1.8.0版本

【实例简介】jdk1.8版本,亲测可用。望有需求人士放心使用,下载。【实例截图】【核心代码】31449426-2a86-4e86-9718-9b4327dbb178└── jdk-8u161-windows-x64├── 1041│ ├── [5]DigitalSignature│ ├── [5]MsiDigitalSignatureEx│ ├─…

定制自己的Windows CE 5.0 ARM中文模拟器(转)

定制自己的Windows CE 5.0 ARM中文模拟器(转)http://showvi.com/Blog/ViewAirticle/59一、生成OS 1. 安装Windows CE 5.0(记得CPU类型里把ARMV4I选上)装完之后装DeviceEmulatorBSP.msi,这是ARMV4I模拟器的BSP。 我补充个DeviceEmulatorBSP.ms…

Spring Data JPA 从入门到精通~@Version处理乐观锁的问题

Version 处理乐观锁的问题 Version 乐观锁介绍 我们在研究 Auditing 的时候,发现了一个有趣的注解 Version,源码如下: package org.springframework.data.annotation; /*** Demarcates a property to be used as version field to impleme…

人工智能即服务 当人工智能遇到云计算

来源:企业网为了在竞争中保持领先地位,越来越多的企业正在寻求将人工智能技术整合到其应用程序、产品、服务,以及大数据分析方法中。而企业开始使用人工智能技术的最简单和最流行的方法之一是使用基于云计算的人工智能即服务产品。根据调研机…

视频裁剪

用【格式工厂FFSetup190.exe】将视频文件格式专程AVI, 再用视频裁剪工具【SolveigMM AVI Trimmer】裁剪需要的段。 源文件-添加视频文件-填入开始时间和停止时间(用三耳确定填写的时间值)-按添加按钮-选择目的文件路径及名称-运行。 转载于:https://www.…

三星s9php禁用列表,ADB禁用列表

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼谷歌程序pm uninstall --user 0com.google.android.ext.servicespm uninstall --user 0com.google.android.onetimeinitializerpm uninstall --user 0com.google.android.ext.sharedpm uninstall --user 0com.google.android.confi…

Linux 文件 IO

参考:http://blog.csdn.net/wanxiao009/article/details/5648583 C 和 C 文件操作详解:http://blog.csdn.net/freeking101/article/details/60959624 标准IO与文件IO 的区别:http://blog.csdn.net/big_bit/article/details/51804391 参考…

Spring Data JPA 从入门到精通~默认数据源的讲解

默认数据源 spring.datasource.driver-class-namecom.mysql.jdbc.Driver spring.datasource.urljdbc:mysql://127.0.0.1:3306/test?useSSLfalse spring.datasource.usernameroot spring.datasource.password123456 但是在实际工作中不可能这么简单,因为会用其他数…

国内AI芯片百家争鸣,何以抗衡全球技术寡头

来源:中国科学院自动化研究所 作者:吴军宁如果说 2016 年 3 月份 AlphaGo 与李世石的那场人机大战只在科技界和围棋界产生较大影响的话,那么 2017 年 5 月其与排名第一的世界围棋冠军柯洁的对战则将人工智能技术推向了公众视野。阿尔法狗&am…

zabbix php 5.6 安装配置,CentOS 5.6下Zabbix 1.8.5 服务端安装部署

CentOS 5.6下Zabbix 1.8.5 服务端安装部署CentOS 5.6 x86_64 Zabbix 1.8.5IP:192.168.88.130一、安装LAMP环境依赖包:# yum install MySQL-server mysql-devel libcurl-devel net-snmp-devel php php-gd php-xml php-mysql php-mbstring php-bcmath httpd curl-dev…

Linux系统编程——I/O多路复用select、poll、epoll

参考:https://segmentfault.com/a/1190000003063859 Linux下的I/O复用与epoll详解:https://www.cnblogs.com/lojunren/p/3856290.html 彻底学会 epoll 系列:http://blog.chinaunix.net/uid/28541347/sid-193117-list-1.htm Linux下I/O多路复用…

Spring Data JPA 从入门到精通~AliDruidDataSource的配置

AliDruid 配置方法 &#xff08;1&#xff09;在实际工作中&#xff0c;由于 HikariCP 和 Druid 应该各有千秋&#xff0c;会发现偏向于监控&#xff0c;有很多国内开发 者使用频次最高的 AliDruid&#xff0c;我们来看看看如何配置。 <!--druid--><dependency>&…