import types
import select
import time
import socket
import functools
import collections class Future:
def __init__(self, *, loop=None):
self._result = None
self._callbacks = []
self._loop = loop def set_result(self, result):
self._result = result
callbacks = self._callbacks[:]
self._callbacks = []
for callback in callbacks:
self._loop._ready.append(callback) def add_callback(self, callback):
self._callbacks.append(callback) def __iter__(self):
print("挂起在yield处")
yield self
print("恢复执行")
return "future" __await__ = __iter__ class Task:
def __init__(self, cor, *, loop=None):
self.cor = cor
self._loop = loop def _step(self):
cor = self.cor
try:
result = cor.send(None)
except StopIteration as e:
self._loop._task_count -= 1
if self._loop._task_count == 0:
self._loop.close()
except Exception as e:
pass
else:
if isinstance(result, Future):
result.add_callback(self._wakeup) def _wakeup(self):
self._step() class Loop:
def __init__(self):
self._stop = False
self._ready = []
self._scheduled = []
self._time = lambda: time.time()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(False)
self._select = functools.partial(select.select, [sock], [], [])
self._task_count = 0 def create_task(self, cor):
task = Task(cor, loop=self)
self._ready.append(task._step)
self._task_count += 1
return task def call_later(self, delay, callback, *args):
callback._when = delay
self._scheduled.append((callback, *args)) def run_until_complete(self, task):
assert isinstance(task, Task)
timeout = None
while not self._stop:
if self._ready:
timeout = 0
if self._scheduled:
callback, *args = self._scheduled.pop()
timeout = callback._when
self._ready.append(functools.partial(callback, *args)) self._select(timeout)
n = len(self._ready)
for i in range(n):
step = self._ready.pop()
step() def close(self):
self._stop = True @types.coroutine
def _sleep():
yield async def sleep(s, result=None):
if s <= 0:
await _sleep()
return result
else:
future = Future(loop=loop)
future._loop.call_later(s, unless_cancelled, future)
await future
return result def unless_cancelled(future):
future.set_result(None) class Lock:
def __init__(self, *, loop=None):
self._waiters = collections.deque()
self._locked = False
self._loop = loop def __repr__(self):
extra = 'locked' if self._locked else 'unlocked'
if self._waiters:
extra = '{},waiters:{}'.format(extra, len(self._waiters))
return '<[{}]>'.format(extra) def locked(self):
"""Return True if lock is acquired."""
return self._locked @types.coroutine
def acquire(self):
if not self._locked:
self._locked = True
return True fut = Future(loop=self._loop)
self._waiters.append(fut) try:
yield from fut
finally:
self._waiters.remove(fut) self._locked = True
return True def release(self):
if self._locked:
self._locked = False
self._wake_up_first()
else:
raise RuntimeError('Lock is not acquired.') def _wake_up_first(self):
"""Wake up the first waiter if it isn't done."""
try:
fut = next(iter(self._waiters))
except StopIteration:
return fut.set_result(True) async def foo(look):
await look.acquire()
print(f'enter foo at {time.strftime("%Y-%m-%d %H:%M:%S")}')
await sleep(1)
print(f'exit foo at {time.strftime("%Y-%m-%d %H:%M:%S")}')
look.release() async def goo(look):
await look.acquire()
print(f'enter goo at {time.strftime("%Y-%m-%d %H:%M:%S")}')
await sleep(1)
print(f'exit goo at {time.strftime("%Y-%m-%d %H:%M:%S")}')
look.release() if __name__ == '__main__':
loop = Loop()
look = Lock(loop=loop)
f = foo(look)
g = goo(look)
task1 = loop.create_task(f)
task2 = loop.create_task(g)
loop.run_until_complete(task1)

asyncio系列之Lock实现的更多相关文章

  1. java多线程系列(四)---Lock的使用

    Lock的使用 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理 ...

  2. asyncio系列之sleep()实现

    先来看个例子,自己实现的模拟耗时操作 例1 import types import select import time import socket import functools class Fu ...

  3. 【面试普通人VS高手系列】lock和synchronized区别

    今天来分享一道阿里一面的面试题,"lock和synchronized的区别". 对于这个问题,看看普通人和高手的回答! 普通人: 嗯,lock是J.U.C包里面提供的锁,synch ...

  4. 并发编程系列之Lock锁可重入性与公平性

    一.相似之处:Lock锁 vs Synchronized 代码块 Lock锁是一种类似于synchronized 同步代码块的线程同步机制.从Java 5开始java.util.concurrent. ...

  5. C#系列教程——lock语句定义及使用

    代码如下: using System; using System.Threading; class Thread_Test { public void Run() { Console.WriteLin ...

  6. 关于asyncio知识(四)

    一.使用 asyncio 总结 最近在公司的一些项目中开始慢慢使用python 的asyncio, 使用的过程中也是各种踩坑,遇到的问题也不少,其中有一次是内存的问题,自己也整理了遇到的问题以及解决方 ...

  7. python异步编程模块asyncio学习(二)

    尽管asyncio应用通常作为单线程运行,不过仍被构建为并发应用.由于I/O以及其他外部事件的延迟和中断,每个协程或任务可能按一种不可预知的顺序执行.为了支持安全的并发执行,asyncio包含了thr ...

  8. 抽丝剥茧分析asyncio事件调度的核心原理

    先来看一下一个简单的例子 例1: async def foo(): print('enter foo ...') await bar() print('exit foo ...') async def ...

  9. asyncio:python3未来并发编程主流、充满野心的模块

    介绍 asyncio是Python在3.5中正式引入的标准库,这是Python未来的并发编程的主流,非常重要的一个模块.有一个web框架叫sanic,就是基于asyncio,语法和flask类似,使用 ...

随机推荐

  1. jieba.lcut方法

    jieba库的作用就是对中文文章进行分词,提取中文文章中的词语 cut(字符串, cut_all,HMM) 字符串是要进行分词的字符串对象 cut_all参数为真表示采用全模式分词,为假表示采用精确模 ...

  2. 线程_进程间通信Queue合集

    # Queue的工作原理 from multiprocessing import Queue q = Queue(3)#初始化一个Queue对象,最多可接收3条put消息 q.put("In ...

  3. Numpy改变数组的形状

    import numpy as np n = np.arange(10) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) # 查看数组的大小 n.size # # 将数 ...

  4. PHP date_add() 函数

    ------------恢复内容开始------------ 实例 添加 40 天到 2013 年 3 月 15 日: <?php$date=date_create("2013-03- ...

  5. PHP date_parse() 函数

    ------------恢复内容开始------------ 实例 返回一个包含指定日期的详细信息的关联数组: <?phpprint_r(date_parse("2013-05-01 ...

  6. PHP registerXPathNamespace() 函数

    实例 为下一个 XPath 查询创建命名空间上下文: <?php$xml=<<<XML高佣联盟 www.cgewang.com<book xmlns:chap=" ...

  7. NodeJS 极简教程 <1> NodeJS 特点 & 使用场景

    NodeJS 极简教程 <1> NodeJS 特点 & 使用场景 田浩 因为看开了所以才去较劲儿.   1. NodeJS是什么 1.1 Node.js is a JavaScri ...

  8. 关于SqlServer那些事1(回归基础)

    即将实习,回归基础总结,希望可以再好好打磨一下基础的一些东西 关于如何在重新修改表结构时该变其权限设置 步骤: 点击工具 进入选项 设计器 取消勾选阻止保存要求重新创建表的更改 关于创建创建数据库以及 ...

  9. Shiro探索1. Realm

    1. Realm 是什么?汉语意思:领域,范围:王国:这个比较抽象: 简单一点就是:Realm 用来对用户进行认证和角色授权的 再简单一点,一个用户怎么判断它有没有登陆?这个用户是什么角色有哪些权限? ...

  10. 当asp.net core偶遇docker一(模型验证和Rabbitmq 一)

    比如我们有一些设计,依赖于某些软件,比如rabbitmq 当管理员功能,反复错误三五次之后,就发送一条消息到队列里去,我们又不希望对原先设计带来侵入式的改变业务 这个时候,我们就可以在模型验证里面加入 ...