我正在尝试使用C进行协程和继续.我意识到我需要某种意大利面堆叠.是否可以在新的调用堆栈中执行函数?当然在单线程内.如何创建一个新的,分离的调用堆栈,并在其上执行一些代码?
我刚刚开始学习Unity脚本,并且很难理解为什么有些人比状态机更喜欢协程。
我确实知道某些程序员可能更容易理解代码,但我不明白为什么有人说使用协程对性能更可取。
我在Unity中使用C#,据我所知,C#编译器将IEnumerator转换为状态机。
所以也许我在这里错过了一些东西。使用协程而不是FSM循环来处理行为和状态是否对运行时性能更好?如果是,为什么?
我对非阻塞IO的概念不熟悉,并且有一些我无法理解的问题 - 关于协同程序.考虑这段代码:
class UserPostHandler(RequestHandler):
@gen.coroutine
def get(self):
var = 'some variable'
data = json.loads(self.request.body)
yield motor_db.users.insert({self.request.remote_ip: data})#asynch non blocking db insert call
#success
self.set_status(201)
print var
Run Code Online (Sandbox Code Playgroud)
get调用函数时,它会创建字符串var.当函数等待motor.insert完成时,该变量会发生什么?据我所知,"非阻塞"意味着没有线程在等待IO调用完成,并且在等待时没有使用内存.那么var存储的价值在哪里?执行恢复时如何访问?
任何帮助,将不胜感激!
根据网上的几个例子,为了运行用来自同步代码的tornado.gen.coroutine装饰的异步方法,你可以使用以下命令:
@tornado.gen.coroutine
def do_something():
do_something
if __name__ == "__main__":
tornado.ioloop.IOLoop.instance().run_sync(do_something)
Run Code Online (Sandbox Code Playgroud)
但是,如果你有coroutine方法的参数,有没有办法运行它?
由于某种原因,该程序打印以下警告:
Task exception was never retrieved
future: <Task finished coro=<coro() done, defined at /usr/lib64/python3.4/asyncio/coroutines.py:139> exception=SystemExit(2,)>
Run Code Online (Sandbox Code Playgroud)
即使异常被清楚地检索和传播,如caught SystemExit!打印到终端,并且进程状态代码变为2.
Python 2和trollius也是如此.
我错过了什么吗?
#!/usr/bin/env python3
import asyncio
@asyncio.coroutine
def comain():
raise SystemExit(2)
def main():
loop = asyncio.get_event_loop()
task = loop.create_task(comain())
try:
loop.run_until_complete(task)
except SystemExit:
print("caught SystemExit!")
raise
finally:
loop.close()
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud) 据我所知,从文档yield()功能是将控制传递给另一个光纤.如果我们不在D中称光纤产量会怎样?这是否意味着线程会挂起?
或者我错了理解纤维在线程内部工作并且它们在内部工作?并且流程可以有threads或者fibers?
使用kotlinx.coroutines lib如果在取消协程后抛出异常,我就无法捕获异常.这会导致应用崩溃.
fun foo() {
val job = launch(UI) {
try {
Log.d("TAG", "Start coroutine")
run(CommonPool) {
Log.d("TAG", "Start bg task")
// Intentionally make bg task running for a long time
SystemClock.sleep(2000)
Log.d("TAG", "Throw bg task exception")
throw RuntimeException("Bg task exception")
}
} catch (e: Exception) {
Log.e("TAG", "Handle coroutine exception", e)
}
}
launch(UI) {
delay(1000)
Log.d("TAG", "Cancel job = ${job.cancel()}")
}
Run Code Online (Sandbox Code Playgroud)
}
在Android上运行此功能会生成以下日志输出
07-26 15:09:10.038 31518-31518/co.foo.bar D/MainActivity: Start coroutine
07-26 15:09:10.044 31518-31547/co.foo.bar D/MainActivity: Start bg task
07-26 …Run Code Online (Sandbox Code Playgroud) 有没有Kotlin相当于C#的任务.什么时候?
我想出了下面的代码,但我想知道是否可以编写whenAll它只能暂停一次.
fun main(args: Array<String>) = runBlocking {
println("Start")
val serviceA = KotlinServiceA()
val serviceB = KotlinServiceB()
val deferredA = async(CommonPool) { serviceA.operationA() }
val deferredB = async(CommonPool) { serviceB.operationB() }
var tasks = arrayOf(deferredA, deferredB)
tasks.whenAll()
println("End")
}
suspend fun Array<Deferred<Unit>>.whenAll() : Unit {
for (task in this) {
task.await()
}
}
Run Code Online (Sandbox Code Playgroud) 我必须发送大量HTTP请求,一旦所有HTTP请求都返回,程序就可以继续.听起来像是一场完美的比赛asyncio.有点天真,我把我的电话包裹requests在一个async函数中,然后把它们给了asyncio.这不起作用.
在线搜索后,我找到了两个解决方案:
asynciorun_in_executor为了更好地理解这一点,我写了一个小基准.服务器端是一个烧瓶程序,在回答请求之前等待0.1秒.
from flask import Flask
import time
app = Flask(__name__)
@app.route('/')
def hello_world():
time.sleep(0.1) // heavy calculations here :)
return 'Hello World!'
if __name__ == '__main__':
app.run()
Run Code Online (Sandbox Code Playgroud)
客户是我的基准
import requests
from time import perf_counter, sleep
# this is the baseline, sequential calls to requests.get
start = perf_counter()
for i in range(10):
r = requests.get("http://127.0.0.1:5000/")
stop = perf_counter()
print(f"synchronous took {stop-start} seconds") # 1.062 secs …Run Code Online (Sandbox Code Playgroud) 我对协程suspended在主线程上的内部工作感到好奇。真正的问题是如何suspended在主线程上记录作为协程的函数。究竟在哪里执行死刑?它是虚拟线程吗?