- 主题:gcc是不是symmetric transfer的支持有问题?
对啊。coroutine 就是为了对付所有的异步调用。有了 coroutine 以后就再也不需要回调函数了。
你可以看看 python, js, c# 程序员在十年前已经用上 coroutine,用来写网络程序。
除此之外,还有 python 的:
for i in range(10):
print(i)
这个 range() 函数也是个协程。也就是 c++20 里面所谓的对称转移,主贴所讨论的场景。
你在主贴里面实现是两个协程来回切换。
用于驱动各种异步事件的时候,得弄个事件循环协程:
<-> coro1(send)
ev_coro <-> coro2(recv)
<-> coro3(timer)
你主贴的场景和 range() 是:
main <-> range()
这种两个协程切来切去还有个绝佳用途就是编译器:
parser <-> lexer
【 在 allegro 的大作中提到: 】
: c++的coroutine的确有传染问题,所以它有自己受限的使用场景。
: 我的感觉是,这个模型特别适合异步消息驱动模型,因为每个消息的处理都是相对独立的,可以从一个消息的处理函数入口斩断传染。消息驱动会有一个dispatch消息的loop,刚好用来resume挂起的协程。
: 并且消息驱动的核心代码少,需要高效简洁。可以让专业的人,使用传统方式实现和维护。(比方于用户代码和内核代码的区别),而项目的主要部分是消息处理函数,用coroutine来写,逻辑更加清楚。也降低了对程序员的水平要求。
: ...................
--
修改:hgoldfish FROM 110.84.121.*
FROM 110.84.121.*
我举例的 task_manager 是个普通类型。不是啥特别的东西。
关键你仔细看 &task 这个参数。。
【 在 ylh1969 的大作中提到: 】
: 使用现成的轮子,问题就在这里,我不知道stack-manage()里边干了啥,出了问题就很难找。
--
FROM 110.84.121.*
唉。你还是没看明白。把这个 Task 改成 User 吧。
void my_coroutine() {
User user;
set_request_user(&user);
send_data_to_remote();
}
这样能理解了吗?这个 user 申请在栈里面,但是指针被传递去了别的地方。
【 在 ylh1969 的大作中提到: 】
: 我不会这么用。
: 我的task里保留的是uc(user context 协程栈)和tc(thread context,线程栈),两套环境的动态资源,想切哪个切哪个。
: 你说的这些,man一下ucontext应该有完整说明。
: ...................
--
FROM 110.84.121.*
有没有云风不重要。关键是你俩的实现是一样的。
【 在 ylh1969 的大作中提到: 】
: 我干完这个事还没有风云呢。
--
FROM 110.84.121.*
所以你可以看去看别人对这些协程实现的分析啊。
你们俩的实现是一样的,所以对云风的分析也适合你的。
【 在 ylh1969 的大作中提到: 】
: 如果它也搞动态栈分配,那是英雄所见略同。
: 定义好资源的生命期,处理好资源的投放和回收,实践证明这个方案是可靠的。
--
FROM 110.84.121.*
stackless 和 stackful 有各自的应用场景。那些不重要。
我是跟你说啊,你那种切换栈空间的玩法是很危险的。
性能怎么样啊,能不能实现目标啊这些先别说。。至少先别搞出崩溃啊。
切换栈空间是有机率搞出野指针的啊。
你的框架如果还是决意使用栈空间切换,那就只能给你自己用了。交给第三人使用就容易出错还找不到 BUG 在哪里。
【 在 ylh1969 的大作中提到: 】
: 我的还真叫task。但是不会交给搞不清楚的函数去管理它的资源。不会这么用,也不会出现你说的问题。
: 争论的关键是,我认为,stackless没有实用价值。动态栈分配是个抛砖引玉。你也不要拘泥于stackless,可以思考更好的方法,届时再讨论。
--
修改:hgoldfish FROM 110.84.121.*
FROM 110.84.121.*
嗯。没错,只管栈的。这本来也没问题。ucontext 当然是没问题的,不然早就从 POSIX API 里面删掉了。
c++20 则是把内存申请在堆里面。这就是为啥 c++20 是安全可靠的,而你弄的那一套栈切换是有问题的。如果那么简单,开源世界早就流行了。
再强调一遍,ucontext 没问题。是你弄的栈切换有问题。
解决办法也很简单,就是别用什么栈切换。
linux/openbsd 都提供了 mmap(MAP_GROWDOWN | MAP_STACK),你用这个申请栈空间,系统帮你做好了内存的自动增长。windows 也有这个功能。
【 在 ylh1969 的大作中提到: 】
: 那几个函数只管ucontext里的栈,不管来自哪里。
--
修改:hgoldfish FROM 110.84.121.*
FROM 110.84.121.*
没有临界区。但不代表没有锁啊。
锁是同步原型,当你涉及到两个变量的修改,中间存在协程阻塞的时候仍然是需要加锁的。
【 在 ylh1969 的大作中提到: 】
: 动态栈空间管理,就是用mmap呀,定义好生命周期和资源投放回收,临界区(4个月的debug,就是处理临界区)处理这些,就没问题,已经投产使用啦。框架调好了,各种应用都没问题。
: 单线程协程没有临界区,简单多了。你不妨试试。
: 临界区就是一个任务还没有swap完成,另一个线程就拿到这个任务并企图处理它。
: ...................
--
FROM 110.84.121.*
有协程锁的。
你可以看看 python 都有实现。
【 在 ylh1969 的大作中提到: 】
: 嗯。
: 要有协程锁,线程锁是锁不住的,都在一个线程里,谁也锁不住谁。
: 自己弄个软锁了,没有原子性,那个缝挺难办的。
: ...................
--
FROM 110.84.121.*
C++ 生态的协程库,最完善的是可能我那一套 qtng 了。
虽然 qtng 性能不怎么样,基本没做性能优化。但论 API,还真的是我的最丰富。
因为我就简单抄 Python 的就完事了。Python 有的我就抄,没有的我只添加了一丁点儿。
qtng = gevent + requests + pycrypt + quic
【 在 ylh1969 的大作中提到: 】
: 嗯。
: c库基本协程工具不负责处理这个问题,得自己弄。
: 那么,c++协程库,有谁提供?
: ...................
--
修改:hgoldfish FROM 110.84.121.*
FROM 110.84.121.*