- 主题:stackoverflow 有个比较 c++ stackful 和 stackless 协程的帖子
stackless 还有很多更蠢的地方。
比如 operator +(),考虑一下这个函数要怎么弄成 stackless 里面可以用的:
obj operator+(obj o1, obj o2) {
int r = (co_await o1.fetch_some_from_network()) + (co_await o2.fetch_some_from_network());
return obj.from_int(r);
}
然后怎么写?
o1 + o2
好像不太行
co_await (o1 + o2)?
也不对。
【 在 allegro 的大作中提到: 】
: 对这个问题记忆深刻。
: 的确要一层一层的遍历下去找到当前handle,但是我记得应该可以把handle存起来?
: 我当时也在想要不要存起来,后来觉得自己没有deep call,遍历更简单就没那么做。
: ...................
--
FROM 110.81.0.*
为什么 fiber 这么烂?按说 fiber 只有在创建和销毁的时候才会申请内存的吧。
【 在 mvtec 的大作中提到: 】
: fiber的运行速度跟屎一样
: 还真敢用
: 我们有个feed handler
: ...................
--
FROM 110.81.0.*
operator + () 里面不是问题。。
我是说要怎么样调用这个 operator+() 才是问题。直接: o1 + o2 是不行的,没有地方放 co_await 这个操作符。
类似的问题 python 和 javascript 都有,所以 python 后面发明了一大堆新的函数,比如 __aenter__(), __aexit__() 之类的,还有 async for 和 async with 这些语法,但 python 还是支持不了 __getitem__(), __add__() 的异步版本。
从这方面来讲,python 比 javascript 还烂,毕竟 javascript 本来就不支持运算符重,而 python 有。
依我看,python 现在非常需要发布一个 py 4.0 版本,去掉 async/await 语法。
【 在 ensonmj 的大作中提到: 】
: 这个语法问题,用rust的语法应该解决:o1.await+o2.await
--
修改:hgoldfish FROM 110.81.0.*
FROM 110.81.0.*
stackful 协程一般是在创建协程的时候申请内存的啊。如果优化得好的话,前一个协程释放的内存可以给下一个协程使用,应该是反而减少了内存操作,而且因为协程里面运行的函数都可以方便地从栈里面申请内存,应该能够有效地提高内存数据的局部性。
我感觉应该是你们怎么用错了。
【 在 mvtec 的大作中提到: 】
: 所有的async 都有这个尿性
: 必须在内存中创建一个区域,
: 否则你怎么获得执行后的结果
: ...................
--
FROM 110.81.0.*
你们可以写个最小测试用例看看。
按我的理解,fiber 是不会有这个问题的。
【 在 mvtec 的大作中提到: 】
: fiber内部
: 总之世界上没有免费的午餐
: 你想想你的async产生一个continue之后
: ...................
--
FROM 110.81.0.*
这个太简单了。弄个生产者消费者队列就行了。每个线程启动 100 个协程,一共 16 个核心是 1600 个协程。这些协程都在消费者队列里面抢任务。
如果打算节约资源,就在每个线程里面启动一个监管协程,检测空闲协程的数量。空闲协程太多,就杀掉一些协程,少了就再启动预备状态的协程。
由编程语言,比如 go, java, c# 那样子把协程自动地在各种线程之间调来调去一般都是没有必要的。
【 在 ylh0315 的大作中提到: 】
: 其实重点是,在高频交易系统中,在交易管理环节,需要协程技术,而且是多线程的协程。需要高效率的切换,一个服务完成后,尽可能快速切换到另一个用户,尽量减少服务的空等时间。
: 有点像银行的排队机,一个窗口空了,马上叫下一位。
: 单线程的协程不行,一个连接空闲了,线程还在别的协程忙活,慢慢悠悠轮到这个协程再处理。
: ...................
--
FROM 110.81.0.*
这个是基于处理 socket 连接,源于 unix 系统可以由多个线程抢同一个 listening socket. 这个机制受系统的影响比较大,有一定的可能性几个线程抢了所有的 accepted socket, 而大部分线程饿死。
所以如果协程是处理其它事情,或者想要更好的负载均衡效果,最好是搞自定义的队列。
【 在 ylh0315 的大作中提到: 】
: 预备一定数量的context池(协程),客户端连接一个分配一个,设置好epoll等待呼叫。然后如楼上所说。最后,disconnect时销毁并归还context。
--
FROM 110.81.0.*
这个 SSL_do_handshake() 可能是个巨坑。楼上不一定有处理清楚:
1. 一般说接收连接,都是一个协程专门 accept(),成功之后 spawn 一个新协程处理这个连接。这里要特别注意 handshake() 的调用时机,必须在子协程里面,而不能是 accept() 的这个协程。不然会卡 accept() 协程。造成不能继续处理连接。
2. 要把 SSL 变成异步的,这个可不简单。需要反复处理 SSL_ERROR_WANT_READ 和 SSL_ERROR_WANT_WRITE 不容易写好。
3. 碰到 SSL_ERROR_SYSCALL 和 SSL_ERROR_SSL 要调用 ERR_get_error() 清理掉错误码,不然整个线程里面所有协程的 SSL 连接都会出错。所以处理 SSL 的协程也不要在线程之间调度来调度去的。
用好协程不是件容易的事。
【 在 wallyz 的大作中提到: 】
: 如果说"密钥协商,和登录认证"造成了“IO长时间占用线程”的话,那应该说明的是,之前“接续模式”的程序本身的IO方式有些问题
: 因为SSL_do_handshake本身支持以非阻塞方式进行,主要是适当的处理SL_ERROR_WANT_READ和SSL_ERROR_WANT_WRITE;
: 登录认证就更不用说了,肯定只是一些应用层的消息交互,如果设计没问题,这必然不可能造成IO长时间占用线程
: ...................
--
FROM 120.33.8.*
timerfd 是 linux 下才能使用的吧。
太丑了,如果是 C++,对着那个协程抛出异常就行了。但是需要注意整个 C++ 程序都得搞 RAII, 不然会有资源泄露。
【 在 ylh0315 的大作中提到: 】
: 嗯。考虑的过timerfd的方案。主要是得解决一个context同时被两个线程处理的情况。
--
FROM 120.33.8.*
timerfd 要陷入内核态的。这个方案也太差了吧。一般是 epoll() 那边带一个超时参数搞定。不过新的 uring 好像没超时参数了。
【 在 ylh0315 的大作中提到: 】
: 嗯。说的都是linux。大规模交易系统,WINDOWS太不靠谱了。
--
FROM 183.253.146.*