根据维基百科,协程基于协作多任务处理,这使得它们比线程消耗更少的资源。没有上下文切换,没有阻塞,没有昂贵的系统调用,没有临界区等等。
换句话说,所有这些协程的好处似乎首先来自于禁止多线程。这使得协程本质上是单线程的:实现了并发,但没有真正的并行。
这是真的吗?是否可以使用多线程来实现协程?
我从过去 8 个月开始就开始关注 kotlin 和协同例程,根据我的理解,如果我们将它用作 api 调用的返回类型,那么它并不是流的最佳使用。
例如:
fun getCoutries(): Flow<List<Country>> = flow {
emit(apiInterface.getAllCountries())
}
Run Code Online (Sandbox Code Playgroud)
我在一次性 api 调用中看到类似这样的流的使用,我想知道是否应该阻止这种情况。因为流是一股流,而不是一次射击。
lifeCycleScope.launch {
viewModel.oneItem.collect {
println("one")
}
viewModel.twoItem.collectLatest {
println("two")
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试了这段代码,但它只打印“一个”,而且似乎第二个collectLatest不起作用。这是为什么?
我试图通过在视图模型中使用密封类来发送事件,将事件发送到片段或活动,例如显示小吃店或烤面包,我想知道,通道是流还是共享流的最佳选择?
我试图了解它asyncio.create_task实际上是如何工作的。假设我有以下代码:
import asyncio
import time
async def delayer():
await asyncio.sleep(1)
async def messenger():
await asyncio.sleep(1)
return "A Message"
async def main():
message = await messenger()
await delayer()
start_time = time.time()
asyncio.run(main())
end_time = time.time() - start_time
print(end_time)
Run Code Online (Sandbox Code Playgroud)
该代码大约需要 2 秒。但是如果我对主体进行一些更改,main如下所示:
import asyncio
import time
async def delayer():
await asyncio.sleep(1)
async def messenger():
await asyncio.sleep(1)
return "A Message"
async def main():
task1 = asyncio.create_task(delayer())
task2 = asyncio.create_task(delayer())
await task1
await task2
start_time = time.time()
asyncio.run(main())
end_time = …Run Code Online (Sandbox Code Playgroud) 我想混合 co_yielding 字符串文字和std::strings
Generator<std::string_view> range(int first, const int last) {
while (first < last) {
char ch = first++;
co_yield " | ";
co_yield std::string{ch, ch, ch};
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我想知道 std::string 的生命周期?
如果您知道要string_view立即食用,也许是安全的?
for(auto sv : range(65, 91))
std::cout << sv;
Run Code Online (Sandbox Code Playgroud)
https://godbolt.org/z/d5eoP9aTE
你可以像这样保证安全
Generator<std::string_view> range(int first, const int last) {
std::string result;
while (first < last) {
char ch = first++;
co_yield " | ";
result = std::string{ch, ch, ch};
co_yield result;
}
}
Run Code Online (Sandbox Code Playgroud) 我需要对我的服务器进行异步HTTP调用才能接收XML响应.在我得到响应之后,如果成功则会调用[先前指定的]函数,如果是错误则调用其他函数.
所以我首先想到的是协同程序.不幸的是,在我进行http.get调用后,我无法屈服,因为它会等待整个事情完成.我知道我可以使用单独的函数来读取响应,但是我必须至少等待数据的第一个字节才能触发此函数,这将允许我屈服.无论如何,因为使用协同程序我想做的事情看起来不像是要走的路.
然后我尝试从lua调用一个C函数,创建单独的线程来获取XML,然后在Lua中调用一个函数,但是这不起作用,因为在创建新线程后lua_state会发生变化.在创建线程之前,我可以在堆栈上看到3个参数,并且在创建新线程后[我传递lua_State作为参数]它只有一个.无论如何,根据我的理解,一旦原始的cfunction调用结束,lua_State将被关闭,所以我将无法回拨.
因为我刚开始使用lua而且我对lua到c绑定更不熟悉,所以我只能希望我犯了一些愚蠢的错误,这很容易解决.但是现在我不知道如何进一步发展.
这个问题背后的故事:我将我的游戏从Cocos2D目标C框架移植到Cocos2d-X C++框架.我想使用Lua绑定,因为我认为我将无法将其移植到C++.无论如何,我想在Lua做.所以我有一个场景,有人访问他们在游戏中的库存清单.如果响应是立即的,他们基本上会看到一个打开的窗口,其中包含库存清单.但是,如果需要更长的时间来获取数据[连接问题,服务器过载......无论如何]屏幕将淡出,并且一些表示数据传输的动画将显示在屏幕上.至少这是它如何在游戏的objc版本上工作,我想要同样的事情.
在我的研究中是否有我遗漏的东西,是否有可能做到这一点?
BTW我已经看到了Lua套接字异步调用,它对我没有帮助,因为它仍然会等待转移的开始,然后再启动另一个.
我尝试构建boost asio示例提供的示例代码:http: //www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/example/cpp11/spawn/echo_server.cpp
我复制所有代码并将其放入cpp文件,使用gcc4.7和cmake在linux上编译,与boost coroutine和boost上下文库链接,但链接失败.
输出如下:
Linking CXX executable ../../../output/bin/unit_test
cd /home/watson/ID_project/build/server_linux_makefile_gcc/abc/test/unit/abc_async && /usr/local/bin/cmake -E cmake_link_script CMakeFiles/unit_test.dir/link.txt --verbose=1
/usr/bin/c++ -std=c++11 -O3 -DNDEBUG -pthread -lrt -ltcmalloc -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free CMakeFiles/unit_test.dir/TestFileChannel.cpp.o CMakeFiles/unit_test.dir/TestStreamBuffer.cpp.o CMakeFiles/unit_test.dir/TestTimer.cpp.o CMakeFiles/unit_test.dir/TestThreadPool.cpp.o CMakeFiles/unit_test.dir/TestScheduler.cpp.o CMakeFiles/unit_test.dir/PCH.cpp.o CMakeFiles/unit_test.dir/main.cpp.o CMakeFiles/unit_test.dir/TestUDPNetwork.cpp.o CMakeFiles/unit_test.dir/TestTCPNetwork.cpp.o -o ../../../output/bin/unit_test -rdynamic ../../../../../../install/thirdparty_linux_makefile_gcc/lib/libboost_unit_test_framework-gcc47-mt-1_54.a ../../../../../../install/thirdparty_linux_makefile_gcc/lib/libboost_context-gcc47-mt-1_54.a ../../../../../../install/thirdparty_linux_makefile_gcc/lib/libboost_coroutine-gcc47-mt-1_54.a ../../../../../../install/thirdparty_linux_makefile_gcc/lib/libboost_thread-gcc47-mt-1_54.a ../../../../../../install/thirdparty_linux_makefile_gcc/lib/libboost_filesystem-gcc47-mt-1_54.a ../../../../../../install/thirdparty_linux_makefile_gcc/lib/libyaml-cpp.a ../../../../../../install/thirdparty_linux_makefile_gcc/lib/libmongoc.a ../../../../../../install/thirdparty_linux_makefile_gcc/lib/libboost_system-gcc47-mt-1_54.a ../../../../../../install/thirdparty_linux_makefile_gcc/lib/libprotobuf.a
../../../../../../install/thirdparty_linux_makefile_gcc/lib/libboost_coroutine-gcc47-mt-1_54.a(coroutine_context.o): In function `boost::coroutines::detail::coroutine_context::coroutine_context(void (*)(long), boost::coroutines::stack_context*)':
coroutine_context.cpp:(.text+0x103): undefined reference to `make_fcontext'
../../../../../../install/thirdparty_linux_makefile_gcc/lib/libboost_coroutine-gcc47-mt-1_54.a(coroutine_context.o): In function `boost::coroutines::detail::coroutine_context::jump(boost::coroutines::detail::coroutine_context&, long, bool)':
coroutine_context.cpp:(.text+0x1bc): undefined reference to `jump_fcontext'
collect2: error: ld returned 1 exit …Run Code Online (Sandbox Code Playgroud) 我有一个使用asyncio和await模块的python程序.这是我从这里开始的一个示例程序
.
import asyncio
import os
import urllib.request
import await
@asyncio.coroutine
def download_coroutine(url):
"""
A coroutine to download the specified url
"""
request = urllib.request.urlopen(url)
filename = os.path.basename(url)
with open(filename, 'wb') as file_handle:
while True:
chunk = request.read(1024)
if not chunk:
break
file_handle.write(chunk)
msg = 'Finished downloading {filename}'.format(filename=filename)
return msg
@asyncio.coroutine
def main(urls):
"""
Creates a group of coroutines and waits for them to finish
"""
coroutines = [download_coroutine(url) for url in urls]
completed, …Run Code Online (Sandbox Code Playgroud) goroutine大致相当于python的asyncio任务,还有一个额外的功能,即任何CPU绑定的任务都被路由到一个ThreadPoolExecutor而不是被添加到事件循环中(当然,假设我们使用没有GIL的python解释器)?
我失踪的两种方法之间有什么实质性的区别吗?当然,除了并发性是Go的一个组成部分所带来的效率和代码清晰度之外.
coroutine ×10
android ×3
kotlin ×3
concurrency ×2
kotlin-flow ×2
python ×2
boost ×1
boost-asio ×1
c++ ×1
c++23 ×1
cocos2d-x ×1
go ×1
hyperlink ×1
linux ×1
lua ×1
pthreads ×1
python-3.x ×1