- 主题:用协程不如用go和rust
没人为了协程而协程。
一定是在应用中遇到某种困难才想起协程。
这个应用可能是在某种生态环境中已经存在的了,想改,不那么容易吧?
【 在 munaiyi 的大作中提到: 】
: go 简单,快速上手
: rust 并发安全,该加锁的地方不加的话就编译不过去,睡觉也安稳。
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
看不出这种任务有何使用协程的必要。
是在print期间把资源让给其他协程吗?
【 在 hgoldfish 的大作中提到: 】
: 不对。。协程 coroutine 应该是最基础的抽象。成为各种编程语言的基础概念。
: Python 不就是这样么。
: for i in range(10):
: ...................
--
FROM 221.218.60.*
我用c的协程都是没办法。
我做的是框架,应用是别人写的插件。人家应用可不管你什么同步异步。
在线程池服务器,人家就这么写了:
SendNet(bank,支付请求);
RecvNet(bank,回执);
银行何时回,不知道,人家就这么等着。不多的几个线程,堵死还不容易?
好大一个系统,就为这两句话,换rust?
所以就改RecvNet(),里边加上yield,让线程脱身干别的,等那边回话了,再resume回来接着干。
与上层应用插件没有关系。不需要他们管什么线程协程,同步异步这些p事。
就算是rust,怎么弄这两句话?别让应用逻辑考虑什么协程异步,全透明。
看了你们前边例子,想不出来怎么弄,才能让人家看不出来异步协程啥的。
【 在 munaiyi 的大作中提到: 】
: 是的,但是用c++协程不如用异步方式也许更好。
:
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
谢,懂了。2,就是你之前说的用协程做词法分析。
1,就用13楼的流程。不过,我是用好多线程来干。
一个线程读,分组发给后边一堆线程,进行清洗入库。这样比协程更有效。
【 在 hgoldfish 的大作中提到: 】
: 我举个我最近用上 generator 的例子:
: 1. 有个模块从关系型数据库里面读取数据,清洗后写入到另外一个 OLAP 数据库。第一版的代码,先把数据清洗后,然后一次性入库到 OLAP 数据库。第二版改成 generator,一边清洗,一边入库。同时入库是按 16k 条纪录批量入库,有个缓冲。内存爆降到原来的 10% 不到。
: 2. 我写了一个表达式 DSL,lexer 和 parser 之间使用 generator 通信。所以 parser 是这样调用 lexer 的:
: ...................
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
cout是个IO,看不出这个协程与IO的并行关系。
协程准备数据,cout进行IO,它们还是串行的。
【 在 hgoldfish 的大作中提到: 】
: boost 的 context 以前也区分两种协程的。
: 事实上,c++20 的 coroutine 也支持 python 这种函数的,并不一定需要个调度器。比如:
: // 定义一个生成器函数
: ...................
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
for(i:{1,2,3,4,5})
cout << i;
不是更省事,要协程干啥?
【 在 hgoldfish 的大作中提到: 】
: boost 的 context 以前也区分两种协程的。
: 事实上,c++20 的 coroutine 也支持 python 这种函数的,并不一定需要个调度器。比如:
: // 定义一个生成器函数
: ...................
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
想不好co_await 与 epoll_wait,什么关系,怎么结合起来用。
【 在 hgoldfish 的大作中提到: 】
: boost 的 context 以前也区分两种协程的。
: 事实上,c++20 的 coroutine 也支持 python 这种函数的,并不一定需要个调度器。比如:
: // 定义一个生成器函数
: ...................
--
FROM 221.218.60.*
明白,这只是例子。
不过还是不懂await如何与epoll_wait结合进行协程调度。
【 在 hgoldfish 的大作中提到: 】
: 这个列表经常是不确定的,比如数据来源于网络或者数据库。
:
--
FROM 221.218.60.*
看了你的例子,就是一些语法变化,如parse,只不过把主程序和子程序掉了个个。对性能没有大的影响。
那个数据库洗数据的例子,协程也不如多线程处理的更好。
最需要协程的,就是同步IO异步化,这躲不掉事件处理。
想不出来C++的协程怎么处理的。
C的协程处理这个问题简单而直观。
只不过目前还没有办法把第三方库的底层IO给解放出来,如数据库的IO。
【 在 hgoldfish 的大作中提到: 】
: await, co_yield 都只涉及到纤程的切换。
: epoll_wait() 是给事件循环纤程用的。这个纤程干的事情和操作系统内核差不多,专门搞调度。
: 但是纤程不一定要被某个控制中心调度。就像我前面说的,两个纤程可以自主地来回切换。完全不需要第三者的参与。这个时候,epoll_wait() 就没有用了。
: ...................
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
【 在 hgoldfish 的大作中提到: 】
: 协程本来就只是异步函数的一种写法而已啊。
: 性能是另外的事情。应该通过算法来提升。
: 另外我一直强调说协程是(纤程,线程,进程)三者的抽象。像 golang 的协程和 python 的协程实现就不太一样。
: ...................
还是没有解决异步IO的问题。
思考了一下,在C++协程里,co_yield没有出现context,不知道yield跑哪去了。
所以没办法调度。
不像C的协程,它不是抽象的,是具象的,有一个开放的ucontext,想放哪放哪,搁队列里也行,做自变量提交给函数也行,放epoll里也行。这样怎么调度都方便。
其他语言的也是,如果想调度它,得拿到一个实体,才可以耍。他们太抽象了,看不见摸不着的。
为什么不可以自己调度线程?就是因为不提供线程的实体。
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*