- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
环境:C和micropython虚拟机中的协作RTOS是任务之一。
为了使VM不阻止其他RTOS任务,我在 RTOS_sleep()
中插入vm.c:DISPATCH()
,以便在执行每个字节码后,VM放弃对下一个RTOS任务的控制。
我创建了一个uPy接口(interface),以使用生产者-消费者设计模式从物理数据总线(可能是CAN,SPI,以太网)异步获取数据。
在uPy中的用法:
can_q = CANbus.queue()
message = can_q.get()
can_q.get()
不会阻止RTOS:它轮询C队列,如果未收到消息,它将调用
RTOS_sleep()
使另一个任务有机会填充队列。事情是同步的,因为C队列仅由另一个RTOS任务更新,并且RTOS任务仅在调用
RTOS_sleep()
即
合作时切换
// gives chance for c-queue to be filled by other RTOS task
while(c_queue_empty() == true) RTOS_sleep();
return c_queue_get_message();
can_q.get()
不会阻止RTOS,但它确实会阻止uPy脚本。
async def
(即
协程)一起使用,并且不阻塞uPy脚本。
can_q = CANbus.queue()
message = await can_q.get()
await
?
最佳答案
注意:此答案涵盖CPython和asyncio框架。但是,这些概念应适用于其他Python实现以及其他异步框架。
How do I write a C-function so I can
await
on it?
asyncio.Future
。在返回
Future
之前,该代码必须安排通过某种异步机制设置将来的结果。所有这些基于协程的方法都假定您的程序在某个事件循环下运行,该事件循环知道如何调度协程。
async def
的
await
的等待对象无法通过返回Future来实现,它必须实现协程通常实现的协议(protocol)。这有点像实现自定义
__next__
的迭代器,并且可以代替生成器使用。
await
。除了使用
async def
定义的Python函数外,用户定义的类型还可以通过定义
__await__
特殊方法使对象等待,该方法将Python / C映射到
tp_as_async.am_await
结构的
PyTypeObject
部分。
tp_as_async
字段指定非NULL值。 am_await
成员指向一个C函数,该C函数接受您的类型的实例并返回实现iterator protocol的另一个扩展类型的实例,即,定义 tp_iter
(通常定义为PyIter_Self
)和 tp_iternext
。 tp_iternext
必须推进协程的状态机。 tp_iternext
的每个非异常返回都对应一个暂停,并且最终StopIteration
异常表示协程的最终返回。返回值存储在value
的StopIteration
属性中。 asyncio.get_event_loop()
(和/或接受显式的
loop
参数)来获取其服务。
async def
表示的简单协程,例如
asyncio.sleep()
的等效形式:
async def my_sleep(n):
loop = asyncio.get_event_loop()
future = loop.create_future()
loop.call_later(n, future.set_result, None)
await future
# we get back here after the timeout has elapsed, and
# immediately return
my_sleep
创建一个
Future
,安排它在n秒内完成(其结果被设置),并暂停自身直到将来完成。最后一部分使用
await
,其中
await x
的意思是“允许
x
决定我们现在将暂停还是继续执行”。不完整的将来总会决定暂停,而异步
Task
协程驱动程序的特殊情况使 future 无限期地暂停它们,并将其完成与恢复任务联系起来。其他事件循环(curio等)的挂起机制在细节上可能有所不同,但是基本思想是相同的:
await
是可选的执行挂起。
__await__()
返回一个生成器
async def
函数定义以及
await
悬挂点。删除
async def
非常简单:等效的普通函数只需要返回一个实现
__await__
的对象:
def my_sleep(n):
return _MySleep(n)
class _MySleep:
def __init__(self, n):
self.n = n
def __await__(self):
return _MySleepIter(self.n)
__await__
操作符将自动调用
_MySleep
返回的
my_sleep()
对象的
await
方法,以将等待对象(传递给
await
的所有对象)转换为迭代器。该迭代器将用于询问等待的对象是选择暂停还是提供值。这很像
for o in x
语句调用
x.__iter__()
将可迭代的
x
转换为具体迭代器的方式。
await
返回时,它需要停止迭代。使用生成器作为便利的迭代器实现,
_MySleepIter
看起来像这样:
def _MySleepIter(n):
loop = asyncio.get_event_loop()
future = loop.create_future()
loop.call_later(n, future.set_result, None)
# yield from future.__await__()
for x in future.__await__():
yield x
await x
映射到
yield from x.__await__()
时,我们的生成器必须用尽
future.__await__()
返回的迭代器。否则,如果将来未完成,则
Future.__await__
返回的迭代器将产生结果,并返回将来的结果(在此我们忽略,但
yield from
实际上提供了结果)。
__await__()
my_sleep
的C实现的最终障碍是
_MySleepIter
的生成器的使用。幸运的是,任何生成器都可以转换为有状态的迭代器,该迭代器的
__next__
将执行这段代码直到下一次等待或返回。
__next__
实现生成器代码的状态机版本,其中
yield
通过返回值表示,
return
通过引发
StopIteration
表示。例如:
class _MySleepIter:
def __init__(self, n):
self.n = n
self.state = 0
def __iter__(self): # an iterator has to define __iter__
return self
def __next__(self):
if self.state == 0:
loop = asyncio.get_event_loop()
self.future = loop.create_future()
loop.call_later(self.n, self.future.set_result, None)
self.state = 1
if self.state == 1:
if not self.future.done():
return next(iter(self.future))
self.state = 2
if self.state == 2:
raise StopIteration
raise AssertionError("invalid state")
关于python - python-如何将C函数实现为可等待的(协程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51029111/
我试图让脚本暂停大约 1 秒,然后继续执行脚本,但我似乎无法弄清楚如何做。这是我的代码: function hello() { alert("Hi!") //I need about a 1
wait() 和 wait(timeout) 之间有什么区别。无论如何 wait() 需要等待通知调用,但为什么我们有 wait(timeout)? 那么 sleep(timeout) 和 wait(
我需要做什么: 我有一个带有文件输入和隐藏文本输入的上传表单。用户上传图像,图像被操作,然后发送到远程服务器进行处理,这需要几秒钟,然后远程服务器将最终的图像发送回家庭服务器,并保存在新文件夹中。 J
大家好,我正在使用 Visual C++ 2010,尝试使用 Winsock 编写服务器/客户端应用程序...我不确定为什么,但有时服务器会在 listen() 函数处等待,有时会在 accept 处
任务描述 我为我的 Angular 应用程序实现了 CRSF 保护。服务器检查 crsf token 是否位于请求的 header “X-CSRF-TOKEN”中。如果不是,它会发送一个 HTTP 响
我想做这个例子https://stackoverflow.com/a/33585993/1973680同步。 这是正确的实现方式吗? let times= async (n,f)=>{
我如何将 while 循环延迟到 1 秒间隔,而不会将其运行的整个代码/计算机的速度减慢到一秒延迟(只是一个小循环)。 最佳答案 Thread.sleep(1000); // do nothing f
我知道这是一个重复的问题。但是我无法通过解释来理解。我想用一个很好的例子来清楚地理解它。任何人都可以帮忙吗。 “为什么我们从同步上下文中调用 wait()、notify() 方法”。 最佳答案 当我们
我有一个 click 事件,该事件是第一次从另一个地方自动触发的。我的问题是它运行得太快,因为所需的变量仍在由 Flash 和 Web 服务定义。所以现在我有: (function ($) {
我有如下功能 function async populateInventories(custID){ this.inventories = await this.inventoryServic
我一直对“然后”不被等待的行为感到困扰,我明白其原因。然而,我仍然需要绕过它。这是我的用例。 doWork(family) { return doWork1(family)
我想我理解异步背后的想法,返回一个Future,但是我不清楚异步在一个非常基本的层面上如何表现。据我了解,它不会自动在程序中创建异步行为。例如: import 'dart:async'; main()
我正在制作一个使用异步的Flutter应用程序,但它的工作方式不像我对它的了解。所以我对异步和在 Dart 中等待有一些疑问。这是一个例子: Future someFunction() async {
我在 main.tf 中创建资源组和 vNet,并在同一文件中引用模块。问题是,模块无法从模块访问这些资源。相关代码(删除了大部分代码,只留下相关部分): main.tf: module "worke
我的代码的问题是,当代码第一次运行时,我试图获取的 dom 元素并不总是存在,如果它不存在,那么永远不会做出 promise 。 我是否可以等到 promise 做出后再尝试实现它? 我希望我的最后一
所以,过去几天我一直在研究这段代码,并尝试实现回调/等待/任何需要的东西,但没有成功。 问题是,我如何等待响应,直到我得到两个函数的回调? (以及我将如何实现) 简而言之,我想做的是: POST 发生
谁能帮我理解这一点吗? 如果我们有一个类: public class Sample{ public synchronized method1(){ //Line1 .... wait();
这是我编写的代码,用于测试 wait() 和 notify() 的工作。现在我有很多疑问。 class A extends Thread { public void run() { try
我有以下代码由于语法错误而无法运行(在异步函数外等待) 如何使用 await 定义变量并将其导出? 当我这样定义一个变量并从其他文件导入它时,该变量是只创建一次(第一次读取文件时?)还是每次导入时都创
一个简单的线程程序,其中写入器将内容放入堆栈,读取器从堆栈中弹出。 java.util.Stack; import java.util.concurrent.ExecutorService; impo
我是一名优秀的程序员,十分优秀!