python线程安全的计数器_Python多线程同步Lock、RLock、Semaphore、Event实例

一、多线程同步

由于CPython的python解释器在单线程模式下执行,所以导致python的多线程在很多的时候并不能很好地发挥多核cpu的资源。大部分情况都推荐使用多进程。

python的多线程的同步与其他语言基本相同,主要包含:

Lock & RLock :用来确保多线程多共享资源的访问。

Semaphore : 用来确保一定资源多线程访问时的上限,例如资源池。

Event : 是最简单的线程间通信的方式,一个线程可以发送信号,其他的线程接收到信号后执行操作。

二、实例

1)Lock & RLock

Lock对象的状态可以为locked和unlocked

使用acquire()设置为locked状态;

使用release()设置为unlocked状态。

如果当前的状态为unlocked,则acquire()会将状态改为locked然后立即返回。当状态为locked的时候,acquire()将被阻塞直到另一个线程中调用release()来将状态改为unlocked,然后acquire()才可以再次将状态置为locked。

Lock.acquire(blocking=True, timeout=-1),blocking参数表示是否阻塞当前线程等待,timeout表示阻塞时的等待时间 。如果成功地获得lock,则acquire()函数返回True,否则返回False,timeout超时时如果还没有获得lock仍然返回False。

实例:(确保只有一个线程可以访问共享资源)

import threading

import time

num = 0

lock = threading.Lock()

def func(st):

global num

print (threading.currentThread().getName() + ' try to acquire the lock')

if lock.acquire():

print (threading.currentThread().getName() + ' acquire the lock.' )

print (threading.currentThread().getName() +" :%s" % str(num) )

num += 1

time.sleep(st)

print (threading.currentThread().getName() + ' release the lock.'  )

lock.release()

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

结果:

71709ddecb15d86fea4ad13bfb5cf17b.png

RLock与Lock的区别是:RLock中除了状态locked和unlocked外还记录了当前lock的owner和递归层数,使得RLock可以被同一个线程多次acquire()。

2)Semaphore

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

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

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

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

实例:(同时只有2个线程可以获得semaphore,即可以限制最大连接数为2):

import threading

import time

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

for i in range(4):

t1 = threading.Thread(target=func)

t1.start()

结果:

4fcaf55210d2946e3356a3d40760ae93.png

3) Event

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

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

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

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

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

实例: (线程间相互通信)

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)

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

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

logging.debug("Event is set")

运行结果:

25c8238c68f1faa35540b6155417694c.png

三、其他

1) 线程局部变量

线程局部变量的值是跟线程相关的,区别与全局的变量。使用非常简单如下:

mydata = threading.local()

mydata.x = 1

2)对Lock,semaphore,condition等使用with关键字代替手动调用acquire()和release()。

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

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

相关文章

java地址传递_关于java中是地址传递还是值传递的测试

首先,我的结论是,如果是对对象进行 操作的话,传的是地址,如果是对基本数据类型进行操作的话,传的是值!下面,我再用一个小的实例来测试我的结论:class Person {int age;public void setAge(int a…

java 线程安全问题_java线程安全问题原因及解决办法

1.为什么会出现线程安全问题计算机系统资源分配的单位为进程,同一个进程中允许多个线程并发执行,并且多个线程会共享进程范围内的资源:例如内存地址。当多个线程并发访问同一个内存地址并且内存地址保存的值是可变的时候可能会发生线程安全问…

java里怎么存入数据并进行排序_Java数据结构之排序---插入排序

插入排序的基本介绍:插入排序是对想要排序的序列以插入的方式寻找该元素的适当的位置,从而达到排序的目的。插入排序的基本思想:把n个待排序的元素看成一个有序表和一个无序表,开始时,有序表只有一个元素(整个序列的第…

java ftp读取文件内容_java读取ftp中TXT文件的案例

最近在开发关于java读取ftp中TXT文件,其中有些坑踩了一下,再次做个记录1、读取文件时我会根据文件名称去生成数据库表,oracle数据库对于表名的长度是有限制的,最多30个字符2、对于多个文件的ftp的读取,每次获取文件后再…

java sql server 2016_SQL server 2016 安装步骤

1.进入安装中心:可以参考硬件和软件要求、可以看到一些说明文档2.选择全新安装模式继续安装3.输入产品秘钥:这里使用演示秘钥进行4.在协议中,点击同意,并点击下一步按钮,继续安装5.进入全局规则检查项,这里…

java resource file_Java 获取Resource目录下的文件解决办法

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼Java 获取Resource目录下的 文件有两种方式:Java代码中的类,要获取Resource资源 文件目录 下文件绝对路径寻址注意这个 / 址的是根 目录 ,用绝对路径,可能会出现的问题是,…

java中对象类型转换_Java中的对象的类型转换介绍(附代码)

本篇文章给大家带来的内容是关于Java中的对象的类型转换介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。向上转型:子类对象转为父类,父类可以是接口。公式:Father f new Son(…

java面板中添加面板_如何把窗体加入面板中 java

展开全部一般来说,我们常把JPanel[面板]放到JFrame窗体中但是也有一种内部窗体JInternalFrame ,可以放到其他的容器JDesktopPane里,效果图e69da5e887aa62616964757a686964616f31333363373731如下代码如下import java.awt.*;import java.awt.event.*;import java.beans.Property…

mysql 如果存在修改_mysql如存在并发修改可能,一定要注意保证数据一致性

近日,因人员调整接手了一个其他部门负责的项目。随后发现其中的很多关键环节是没有考虑mysql并发操作的,现列出存在的一例问题 并分享如何解决的。问题描述:用户账户余额转移赠送 (用户A将自己的账户剩余金额赠送给用户B),同一时刻还可能存在…

微信对账单 java_微信支付对账,你是如何处理的?

支付对账,即检查第三方支付与数据库中账单是否一一对应,涉及到微信对账单的处理,成功时,微信账单接口返回数据以文本表格的方式返回,第一行为表头,后面各行为对应的字段内容,字段内容跟查询订单…

java如何处理灰度图片_Java图片的灰度处理方法

通过看网上各种大牛的总结,和自己亲身测试总结一下Java图片的灰度处理方法(1)我们熟知的图片中的像素点有RGB值。(2)图片灰度化的方式大概分为四种,第一种是最大值法(取颜色RGB中的最大值作为灰度值);第二种是最小值法(取颜色RGB的最小值作为…

java jsp校验提示信息_java Jquery表单校验代码jsp页面

jsp.file欢迎注册EasyMall/* 注册表单的js校验 */var formObj {/* 检查输入项是否为空 */"checkNull" : function(name, msg){var value $("input[name"name"]").val().trim();//清空之前的提示消息formObj.setMsg(name, "");if(val…

错误处理方法 java_JAVA常见错误处理方法 和 JVM内存结构

OutOfMemoryError在开发过程中是司空见惯的,遇到这个错误,新手程序员都知道从两个方面入手来解决:一是排查程序是否有BUG导致内存泄漏;二是调整JVM启动参数增大内存。OutOfMemoryError有好几种情况,每次遇到这个错误时…

java中如何分隔字符串_Java中分割字符串

java.lang.String的split()方法, JDK 1.4 or laterpublic String[] split(String regex,int limit)示例代码public classStringSplit {public static voidmain(String[] args) {String sourceStr "1,2,3,4,5";String[] sourceStrArray sourceStr.split(",&quo…

php测试号推送消息失败,信息发送失败是什么原因

手机突然信息发送失败可能是以下原因:1.是因为我们的手机出现了欠费的情况,所以发不出短信,这种情况是最为普遍的,需要我们及时的进行缴费。2.手机的信息中心的号码设置有误,应该根据你所在省份的实际信息中心号码进行设置,这样一般就能解决这方面的问题。可能是你的…

php ajax 概率 转盘,php+jquery实现转盘抽奖 概率可任意调

phpjquery实现转盘抽奖 概率可任意调phpjquery实现转盘抽奖 概率可任意调Posted by: xiaomiao 2014/05/13in Code, PHP 3 Commentsphpjquery实现转盘抽奖查看DEMO演示转盘抽奖,炫丽的一般是flash做的。不懂flash而又不需要那么炫丽,可以简单的通过jquer…

php自动抓取文章图片,从文章中提取图片,把图片保存到本地,自动提取缩略图...

开发二代旅游网站程序和CMS的时候,有一个需求,就是从网上复制的内容,里面包含图片的,需要对把图片提取出来,并且保存到本地,并且把图片的URL地址本地化,以下是实现的代码。开发二代旅游网站程序…

简单的php探针,php探针程序的推荐

在我们之前的文章已经为大家介绍了什么是php探针,以及他的主要作用是什么,如果你接触了cms或许就会有点了解,当然,不要紧,看完这篇就知道php探针是做什么的了。php探针通常是用来探测空间、服务器运行的状况和php相关信…

php熊掌号怎么设置json-ld,dedecms织梦系统对接百度熊掌号并添加JSON_LD数据

百度近期推出的百度熊掌号非常的不错,我的dedecms织梦系统早早就对接好了,它能对你的原创文章进行原创保护,并评出熊掌号搜索指数,熊掌号搜索指数是对你文章的内容质量,用户喜爱、原创能力、活跃表现、领域专注五个维度进行计算评估而得到的。你的dedecms织梦网站开通熊掌号之后…

php获取信息,PHP文件信息获取函数

知识点:basename():获取文件名,传入第二个参数则只显示文件名,不显示后缀dirname():获取文件路径pathinfo():将文件信息存入一个数组,通过索引basename,dirname,extension可以获得对应的文件名,…