我想用一种语言来启动一个新的网络服务器项目,该语言通过光纤aka coroutines即用户模式线程来支持并发.确定我的选项究竟是什么一直非常困难,因为"coroutine"这个术语似乎用得很松散,意味着各种各样的东西,而"fiber"几乎只用于引用Win32 API.
为了这个问题的目的,协同程序/纤维:
我的语言选择是什么?我知道Ruby 1.9和Perl(Coro)都有支持,还有什么?任何具有成熟gc和动态方法调用的东西就足够了.
在Lua 5.1中,从不让协程正常结束有多糟糕?换句话说,如果一个协程收益但是我从来没有恢复它,它是否会在程序完成之前留下很多州?
cor=coroutine.wrap(somefunc)
while true do
done=cor()
if done then -- coroutine exited with "return true"
break
else -- coroutine yielded with "coroutine.yield(false)"
if some_condition then break end
end
end
function somefunc()
-- do something
coroutine.yield(false)
-- do some more
return true
end
Run Code Online (Sandbox Code Playgroud)
根据上面伪代码中的some_condition,协程可能永远不会被恢复,因此可能永远不会正确地"结束".
我可以这样做几十个协同程序而不必担心吗?将协同程序置于此状态是否安全?这个很贵吗?
此示例已用于另一个问题,以说明协同程序如何用于编写视频游戏中的过场动画:
bob.walkto(jane)
bob.lookat(jane)
bob.say("How are you?")
wait(2)
jane.say("Fine")
...
Run Code Online (Sandbox Code Playgroud)
每个函数产生主动引擎,它在恢复协程之前进行动画,定时等.协程的可能替代方案是事件队列而不是代码,但是必须实现控制逻辑和循环作为事件.是否有其他可用于实现此类功能的协同程序的替代方案?我见过一些文章中提到的回调,但我不确定代码的外观.
我刚才读过David Beazley关于协同程序的这个页面,我想知道是否有任何实际的基于Python的软件使用它们?
如何将协同程序看作Python中最常用的功能?
我在python中有一个协程(增强型生成器),在数据结束后要执行一些代码:
def mycoroutine():
try:
while True:
data = (yield)
print data
finally:
raise ValueError
print "END"
co = mycoroutine()
co.next()
for i in (1,2,3):
co.send(i)
Run Code Online (Sandbox Code Playgroud)
该ValueError异常没有提出,但解释简单地打印:
Exception ValueError: ValueError() in <generator object mycoroutine at 0x2b59dfa23d20> ignored
Run Code Online (Sandbox Code Playgroud)
有没有办法在调用者中捕获异常?
我使用以下函数强制协程同步运行:
import asyncio
import inspect
import types
from asyncio import BaseEventLoop
from concurrent import futures
def await_sync(coro: types.CoroutineType, timeout_s: int=None):
"""
:param coro: a coroutine or lambda loop: coroutine(loop)
:param timeout_s:
:return:
"""
loop = asyncio.new_event_loop() # type: BaseEventLoop
if not is_awaitable(coro):
coro = coro(loop)
if timeout_s is None:
fut = asyncio.ensure_future(coro, loop=loop)
else:
fut = asyncio.ensure_future(asyncio.wait_for(coro, timeout=timeout_s, loop=loop), loop=loop)
loop.run_until_complete(fut)
return fut.result()
def is_awaitable(coro_or_future):
if isinstance(coro_or_future, futures.Future):
return coro_or_future
elif asyncio.coroutines.iscoroutine(coro_or_future):
return True
elif asyncio.compat.PY35 and inspect.isawaitable(coro_or_future):
return True …Run Code Online (Sandbox Code Playgroud) 我目前正在尝试在Unity的上下文中理解IEnumerator和Coroutine,并且对"yield return null"执行的内容不太自信.目前我认为它基本上暂停并等待下一帧,并且在下一帧中它将再次执行while语句.
如果我省略"yield return null",它似乎会立即移动到目的地或者"跳过很多帧".所以我想我的问题是在这个while循环中这个"yield return null"函数是如何实现的,为什么有必要这样做.
void Start () {
StartCoroutine(Move());
}
IEnumerator Move(){
while (a > 0.5f){
... (moves object up/down)
yield return null; // <---------
}
yield return new WaitForSeconds(0.5f);
.... (moves object up/down)
StartCoroutine(Move());
}
Run Code Online (Sandbox Code Playgroud) 给定一个返回模型的API(由Retrofit实现).我将一个老式的Call包含在一个Deferred使用extention函数中:
fun <T> Call<T>.toDeferred(): Deferred<T> {
val deferred = CompletableDeferred<T>()
// cancel request as well
deferred.invokeOnCompletion {
if (deferred.isCancelled) {
cancel()
}
}
enqueue(object : Callback<T> {
override fun onFailure(call: Call<T>?, t: Throwable) {
deferred.completeExceptionally(t)
}
override fun onResponse(call: Call<T>?, response: Response<T>) {
if (response.isSuccessful) {
deferred.complete(response.body()!!)
} else {
deferred.completeExceptionally(HttpException(response))
}
}
})
return deferred
}
Run Code Online (Sandbox Code Playgroud)
现在我可以得到这样的模型:
data class Dummy(val name: String, val age: Int)
fun getDummy(): Deferred<Dummy> = api.getDummy().toDeferred()
Run Code Online (Sandbox Code Playgroud)
但是如何修改里面的对象 …
背景:我是一位经验丰富的Python程序员,对新的协程/异步/等待功能一无所知。我无法编写一个异步的“ hello world”来挽救生命。
我的问题是:给我一个任意协程函数f。我想编写一个g将包装的协程函数f,即我将给g用户,就像它是一样f,并且用户将调用它,而没有人会更明智,因为g将在后台使用f。就像装饰普通的Python函数以添加功能时一样。
我要添加的功能:每当程序流进入协程时,它都会获取我提供的上下文管理器,一旦程序流离开协程,它将释放该上下文管理器。流量又回来了吗?重新获取上下文管理器。它退出了吗?重新释放它。直到协程完全完成。
为了演示,这是使用普通生成器描述的功能:
def generator_wrapper(_, *args, **kwargs):
gen = function(*args, **kwargs)
method, incoming = gen.send, None
while True:
with self:
outgoing = method(incoming)
try:
method, incoming = gen.send, (yield outgoing)
except Exception as e:
method, incoming = gen.throw, e
Run Code Online (Sandbox Code Playgroud)
有可能用协程吗?
我刚刚创建了一个应用程序,其中我的函数 getdata() 每秒调用一次以从服务器获取新数据,而 updateui() 函数将更新 UI 中的视图我没有在我的应用程序中使用任何异步任务或协程我想这样做请告诉我我怎么能做到这一点。
这是我的代码...
private fun getdata(){
try {
val api = RetroClient.getApiService()
call = api.myJSON
call!!.enqueue(object : Callback<ProductResponse> {
override fun onResponse(
call: Call<ProductResponse>,
response: Response<ProductResponse>
) {
if (response.isSuccessful) {
productList = response.body()!!.data
for (list in productList) {
if (list.BB.equals("AAA")) {
aProductList.add(list)
}
}
if (recyclerView.adapter != null) {
eAdapter!!.updatedata(aProductList)
}
updateui()
}
}
override fun onFailure(call: Call<ProductResponse>, t: Throwable) {
println("error")
}
})
} catch (ex: Exception) {
} catch (ex: OutOfMemoryError) { …Run Code Online (Sandbox Code Playgroud) coroutine ×10
python ×4
kotlin ×2
android ×1
async-await ×1
c# ×1
event-loop ×1
exception ×1
fiber ×1
generator ×1
hang ×1
ienumerator ×1
lua ×1
rx-java2 ×1
yield ×1