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. 03_Linux定制篇

    第十四章 JAVAEE定制篇 搭建JAVAEE环境 14.1 安装JDK 1)先将软件通过xftp5上传到/opt下 2)解压缩到/opt 3)配置环境变量的配置文件vim/etc/profile J ...

  2. PHP array_key_exists() 函数

    实例 检查键名 "Volvo" 是否存在于数组中: <?php $a=array("Volvo"=>"XC90","B ...

  3. PHP easter_date() 函数

    ------------恢复内容开始------------ 实例 输出不同年份的复活节日期: <?phpecho easter_date() . "<br />" ...

  4. PHP sha1_file() 函数

    实例 计算文本文件 "test.txt" 的 SHA-1 散列: <?php高佣联盟 www.cgewang.com$filename = "test.txt&qu ...

  5. PDOStatement::bindValue

    PDOStatement::bindValue — 把一个值绑定到一个参数(PHP 5 >= 5.1.0, PECL pdo >= 0.1.0) 说明 语法 bool PDOStateme ...

  6. Skill 脚本演示 ycChangeLayerToEntry.il

    https://www.cnblogs.com/yeungchie/ ycChangeLayerToEntry.il 快速切换选中 figs 的 lpp(Layer-Purpose Pair). 回到 ...

  7. 死磕abstractqueuedsynchronizer源码

    第一次写博客,先练练手. 1.AQS是什么? 在Lock中,用到了一个同步队列AQS,全称为AbstractQueuedSynchronizer,它是一个同步工具也是lock用来实现线程同步的核心组件 ...

  8. JDK8的LocalDateTime用法

    参考资料:好好学Java  https://mp.weixin.qq.com/s/Dd_7yUh3lq3TqE2cjsYXvw JDK8新特性里提供了3个时间类:LocalDate.LocalTime ...

  9. Linux学习笔记之配置网络

    1.打开VMware Workstation虚拟机 2.在VMware下安装虚拟ubunt系统后配置网络,如图所示配置,即可. 3.检查笔记本所使用的网段 ①按 “win + R ”键,并输入“cmd ...

  10. 网络协议: TCP/IP 和UDP/IP

    网络协议: TCP/IP 和UDP/IP TCP/IP TCP/IP(Transmission Control Protocol/Internet Protocol)是一种可靠的网络数据传输控制协议. ...