https://github.com/python/cpython/blob/master/Doc/library/contextlib.rst 被同一个线程多次获取的同步基元组件
# -*- coding: utf-8 -*-
import time
from threading import Lock, RLock
from datetime import datetime
from threading import Thread
import threading class Test:
def __init__(self):
self.obj_lock = Lock()
self.obj_rlock = RLock()
self.a = 1
self.b = 2
self.r = 'r' def t(self):
print('123') def a(self):
with self.obj_lock:
print("a")
self.b() def b(self):
with self.obj_lock:
print("b") def ar(self):
with self.obj_rlock:
print("ar")
self.r = 'ar'
self.br() def br(self):
with self.obj_rlock:
print("br")
self.r = 'br' t = Test()
print(t.a)
t.t()
t.ar()
# t.br()
print('t.r', t.r)
https://github.com/python/cpython/blob/master/Doc/library/contextlib.rst
https://github.com/python/cpython/blob/master/Doc/library/contextlib.rst#reentrant-context-managers
Reentrant context managers
More sophisticated context managers may be "reentrant". These context managers can not only be used in multiple :keyword:`with` statements, but may also be used inside a :keyword:`!with` statement that is already using the same context manager.
:class:`threading.RLock` is an example of a reentrant context manager, as are :func:`suppress` and :func:`redirect_stdout`. Here's a very simple example of reentrant use:
>>> from contextlib import redirect_stdout
>>> from io import StringIO
>>> stream = StringIO()
>>> write_to_stream = redirect_stdout(stream)
>>> with write_to_stream:
... print("This is written to the stream rather than stdout")
... with write_to_stream:
... print("This is also written to the stream")
...
>>> print("This is written directly to stdout")
This is written directly to stdout
>>> print(stream.getvalue())
This is written to the stream rather than stdout
This is also written to the stream
Real world examples of reentrancy are more likely to involve multiple functions calling each other and hence be far more complicated than this example.
Note also that being reentrant is not the same thing as being thread safe. :func:`redirect_stdout`, for example, is definitely not thread safe, as it makes a global modification to the system state by binding :data:`sys.stdout` to a different stream.
https://docs.python.org/zh-cn/3/library/threading.html#rlock-objects
重入锁是一个可以被同一个线程多次获取的同步基元组件。在内部,它在基元锁的锁定/非锁定状态上附加了 "所属线程" 和 "递归等级" 的概念。在锁定状态下,某些线程拥有锁 ; 在非锁定状态下, 没有线程拥有它。
acquire(blocking=True, timeout=-1)-
可以阻塞或非阻塞地获得锁。
当无参数调用时: 如果这个线程已经拥有锁,递归级别增加一,并立即返回。否则,如果其他线程拥有该锁,则阻塞至该锁解锁。一旦锁被解锁(不属于任何线程),则抢夺所有权,设置递归等级为一,并返回。如果多个线程被阻塞,等待锁被解锁,一次只有一个线程能抢到锁的所有权。在这种情况下,没有返回值。
当调用时参数 blocking 设置为
True,和没带参数调用一样做同样的事,然后返回True。当 blocking 参数设置为 false 的情况下调用,不进行阻塞。如果一个无参数的调用已经阻塞,立即返回false;否则,执行和无参数调用一样的操作,并返回true。
当浮点数 timeout 参数被设置为正值调用时,只要无法获得锁,将最多阻塞 timeout 设定的秒数。 如果锁被获取返回 true,如果超时返回false。
在 3.2 版更改: 新的 timeout 形参。
release()-
释放锁,自减递归等级。如果减到零,则将锁重置为非锁定状态(不被任何线程拥有),并且,如果其他线程正被阻塞着等待锁被解锁,则仅允许其中一个线程继续。如果自减后,递归等级仍然不是零,则锁保持锁定,仍由调用线程拥有。
只有当前线程拥有锁才能调用这个方法。如果锁被释放后调用这个方法,会引起
RuntimeError异常。没有返回值。
原始锁是一个在锁定时不属于特定线程的同步基元组件。在Python中,它是能用的最低级的同步基元组件,由 _thread 扩展模块直接实现。
、
该模块的设计基于 Java的线程模型。 但是,在Java里面,锁和条件变量是每个对象的基础特性,而在Python里面,这些被独立成了单独的对象。 Python 的 Thread 类只是 Java 的 Thread 类的一个子集;目前还没有优先级,没有线程组,线程还不能被销毁、停止、暂停、恢复或中断。 Java 的 Thread 类的静态方法在实现时会映射为模块级函数。
下列描述的方法都是自动执行的。
https://docs.python.org/zh-cn/3/library/threading.html#thread-local-data
https://tech.meituan.com/2018/11/15/java-lock.html
cpython/blob/master/Modules/_threadmodule.c
拥有的条件
static PyObject *
rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored))
{
unsigned long tid = PyThread_get_thread_ident(); if (self->rlock_count > 0 && self->rlock_owner == tid) {
Py_RETURN_TRUE;
}
Py_RETURN_FALSE;
} 创建
static PyObject *
rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
rlockobject *self; self = (rlockobject *) type->tp_alloc(type, 0);
if (self != NULL) {
self->in_weakreflist = NULL;
self->rlock_owner = 0;
self->rlock_count = 0; self->rlock_lock = PyThread_allocate_lock();
if (self->rlock_lock == NULL) {
Py_DECREF(self);
PyErr_SetString(ThreadError, "can't allocate lock");
return NULL;
}
} return (PyObject *) self;
} static PyObject *
lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
{
_PyTime_t timeout;
PyLockStatus r; if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
return NULL; r = acquire_timed(self->lock_lock, timeout);
if (r == PY_LOCK_INTR) {
return NULL;
} if (r == PY_LOCK_ACQUIRED)
self->locked = 1;
return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
}
如果多线程的场景下,没有在一个线程内的 锁的获取与释放的要求,那么 Rlock的作用 就是否和Lock一样?1
单线程的情况下,lock有的功能点,Rlock也有,反之不成立;
多线程的情况下, 如果有在同一线程内的锁的释放或获取的需求,则用Rlock; 否则,用Lock,因为Rlock的运行逻辑多于Lock,会有更多的资源消耗 性能开销。
https://github.com/python/cpython/blob/master/Doc/library/contextlib.rst 被同一个线程多次获取的同步基元组件的更多相关文章
- https://github.com/chenghuige/tensorflow-exp/blob/master/examples/sparse-tensor-classification/
https://github.com/chenghuige/tensorflow-exp/blob/master/examples/sparse-tensor-classification/ ...
- 结对项目https://github.com/bxoing1994/test/blob/master/源代码
所选项目名称:文本替换 结对人:曲承玉 github地址 :https://github.com/bxoing1994/test/blob/master/源代码 结对人github地址:ht ...
- https://github.com/golang/crypto/blob/master/bcrypt/bcrypt.go
https://github.com/golang/crypto/blob/master/bcrypt/bcrypt.go
- https://github.com/PyMySQL/PyMySQL/blob/master/pymysql/connections.py
# Python implementation of the MySQL client-server protocol # http://dev.mysql.com/doc/internals/en/ ...
- https://github.com/tensorflow/models/blob/master/research/slim/datasets/preprocess_imagenet_validation_data.py 改编版
#!/usr/bin/env python # Copyright 2016 Google Inc. All Rights Reserved. # # Licensed under the Apach ...
- GC 的认识(转) https://github.com/qcrao/Go-Questions/blob/master/GC/GC.md#1-什么是-gc有什么作用
1. 什么是 GC,有什么作用? GC,全称 Garbage Collection,即垃圾回收,是一种自动内存管理的机制. 当程序向操作系统申请的内存不再需要时,垃圾回收主动将其回收并供其他代码进行内 ...
- https://github.com/CocoaPods/CocoaPods/search?q=No+such+file+or+directory报错解决方式
――― MARKDOWN TEMPLATE ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― ### Command ``` /U ...
- 编译python(cpython)的源码及其用途
获取python的源码 3.x及最新版本的源码:https://github.com/python/cpython python2.7分支的源码:https://github.com/python/c ...
- git push ! [rejected] master -> master (non-fast-forward) error: failed to push some refs to 'https://github.com/Operater9/guest' hint: Updates were rejected because the tip of your current bra
推送本地代码到github报错 git push报错 ! [rejected] master -> master (non-fast-forward) error: failed to push ...
随机推荐
- DevOps简介_转
转自:DevOps简介 刘大飞 DevOps 是一个完整的面向IT运维的工作流,以 IT 自动化以及持续集成(CI).持续部署(CD)为基础,来优化程式开发.测试.系统运维等所有环节. Dev ...
- ssh本机失败(ssh: connect to host localhost port 22: Connection refused)
ssh本机失败(ssh: connect to host localhost port 22: Connection refused) 一. 问题描述 之前一直在服务上使用宝塔面板, 今天突发奇想, ...
- sqlite3入门之sqlite3_open,sqlite3_exec,slite3_close
sqlite3_open sqlite3_open函数原型: int sqlite3_open( const char *filename, /* Database filename (UTF-8) ...
- typescript 接口
接口:用来建立某种代码约定,使得其他开发者在调用某个方法或创建新的类时必须遵循接口所定义的代码约定 在js里面没有接口这个概念,在ts里面通过两个关键字来支撑接口这个特性 interface ...
- 基于Java+Selenium的WebUI自动化测试框架(十四)-----使用TestNG的Sample
到目前为止,我们所写的东西,都是集中在如何使用Selenium和Java来定位和读取元素.那么,到底如何具体开展测试,如何实现参数化,如何实现判定呢?下面,我们来看看Java应用程序的测试框架吧. 当 ...
- 2019牛客多校第一场 A.Equivalent Prefixes
题目描述 Two arrays u and v each with m distinct elements are called equivalent if and only if RMQ(u,l,r ...
- ASP.NET MVC 5 入门-2控制器、路由
一.创建项目: 上起始页,选择新项目. 在中新的项目对话框中,右侧语言类别选择C# ,然后项目类型选择Web,然后选择ASP.NET Web 应用程序 (.NET Framework) 项目模板. 将 ...
- YAML_17 Playbook 综合
Playbook1.语法特性如下:(1)"---"首行顶格开始(2)#号注释(3)缩进统一,不同的缩进代表不同的级别,缩进要对齐,空格和tab不能混用(4)区别大小写,键值对k/v ...
- learning java 文件过滤器
import java.io.File; public class FilenameFilterTest { public static void main(String[] args) { var ...
- myaliyun ECS 启动内外穿透工具shell脚本
#!/bin/bash tbp=/usr/local/ngrok cmd=$1 if [[ -z $cmd ]];then echo "err!usage{sh $0 1|0 to star ...