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. Python File next() 方法

    概述 next() 方法在文件使用迭代器时会使用到,在循环中,next()方法会在每次循环中调用,该方法返回文件的下一行,如果到达结尾(EOF),则触发 StopIteration高佣联盟 www.c ...

  2. PHP lcg_value() 函数

    实例 返回范围为 (0, 1) 的一个伪随机数: <?phpecho lcg_value();?>高佣联盟 www.cgewang.com 定义和用法 lcg_value() 函数返回范围 ...

  3. luogu P4206 [NOI2005]聪聪与可可 期望dp 记忆化搜索

    LINK:聪聪与可可 这道题的核心是 想到如何统计答案. 如果设f[i][j]表示第i个时刻... 可以发现还需要统计位置信息 以及上一次到底被抓到没有的东西 不太好做. 两者的位置都在变化 所以需要 ...

  4. x86架构: 硬件启动过程分析(附引导启动代码)

    用户按下开机键,几秒的时间,都经历了啥? 1.cpu各个寄存器赋初始值,cs.base=0xffff0000, eip=0xfff0,其他寄存器都是0,这时cs:ip得到的物理地址:0xfffffff ...

  5. idea中运行Tomcat后控制台出现乱码(统一设置成UTF-8)

    出现问题:运行Tomcat后控制台出现乱码,输出语句乱码(idea 2019.3版本) 解决方法: 方案1:File----->Settings..----->Editor-----> ...

  6. Python机器学习——预测分析核心算法PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书

    点击获取提取码:7qi1 在学习和研究机器学习的时候,面临令人眼花缭乱的算法,机器学习新手往往会不知所措.本书从算法和Python语言实现的角度,帮助读者认识机器学习. 本书专注于两类核心的" ...

  7. 阿里云Redis的开发规范

    作者:付磊-起扬 来源:https://yq.aliyun.com/articles/531067 本文主要介绍在使用阿里云Redis的开发规范,从下面几个方面进行说明. 键值设计 命令使用 客户端使 ...

  8. Qt自定义控件之仪表盘2--QPaint绘制仪表盘

    0.前言 前面一篇文章写道了仪表盘的特点,实现了一个贴图的仪表盘,属于低配版本的仪表盘.    主要是有任何改动时候就需要重新设计图片,不能适配不同控件大小,即使让它自由拉伸,但仪表盘放大缩小时候显示 ...

  9. 区间DP 学习笔记

    前言:本人是个DP蒟蒻,一直以来都特别害怕DP,终于鼓起勇气做了几道DP题,发现也没想象中的那么难?(又要被DP大神吊打了呜呜呜. ----------------------- 首先,区间DP是什么 ...

  10. 恢复HTML表格笔记

            表格         语法:          标记:            <table></table>:表示一个表格                属性: ...