- 主题:gcc是不是symmetric transfer的支持有问题?
这一套要是真的那么好用早就流行起来了。但事实上是没有。
ucontext 这几个函数是不跨平台的,在 windows 下不能用也就算了,连 android 同样是 linux 内核也用不了。
而且因为它申请的 mmap(MAP_GROWDOWN | MAP_STACK) 内存。一次申请 8MB 的话,在以前 32 位机器里,只有 2GB 的内存空间经常不够用。
c++20 能够支持 stackless coroutine 还是更好一些。
现在的问题是 c++20 只提供最基本的协程来回切换的功能,但具体的协程库还需要更多东西,比如事件循环、同步机制等等全都没有,要么程序员自己折腾,要么等标准库、第三方库成熟。而且 co_await 没法处理 operator+() 这特殊函数,没法穿透迭代器。只能说受限于 c++ 的旧语法,协程在 c++20 下永远也没法达到完美,只能凑合凑合。
【 在 ylh1969 的大作中提到: 】
: ucontext不是回调啊,就是coroutine呀!
: 一共4个函数,每个功能都极其简单,非常好理解。
: 由于资源是你自己管理的,这部分代码会有一些。有啥问题自己清楚。
: ...................
--
修改:hgoldfish FROM 110.84.121.*
FROM 110.84.121.*
你这个玩法只能用在自己的项目里。
因为你这个框架没法控制别人堆里有个指针指向栈啊!
【 在 ylh1969 的大作中提到: 】
: 现在都是64位机了吧,资源不是问题。
: stackless没有可用性。
: 我的解决办法是在多线程协程服务器中,只有发出了服务请求并被受理的客户端context,才分配栈,栈的生命期,只存在于本次服务期间,一旦服务完成,context进入等待状态前,收回它的栈。只有活动任务占用栈,等待状态的任务不占用栈。
: ...................
--
FROM 110.84.121.*
你再想想,你切换栈的时候,堆里指向栈的指针怎么办?
【 在 ylh1969 的大作中提到: 】
: ucontect有用户栈呀,任务切换最最重要的,就是切换栈呀!
--
FROM 110.84.121.*
你为啥能打出63+1出来。这个 mgc.
既然已经是 63+1 位计算机,你就没必要折腾这个切换栈的功能。
而在 32 位计算机下,ucontext 这种浪费内存的玩法也约等于没用。
【 在 ylh1969 的大作中提到: 】
: 现在都是64位机了吧,资源不是问题。
: stackless没有可用性。
: 我的解决办法是在多线程协程服务器中,只有发出了服务请求并被受理的客户端context,才分配栈,栈的生命期,只存在于本次服务期间,一旦服务完成,context进入等待状态前,收回它的栈。只有活动任务占用栈,等待状态的任务不占用栈。
: ...................
--
修改:hgoldfish FROM 110.84.121.*
FROM 110.84.121.*
堆啊!
那几个函数只管栈,不管堆的。
ucontext 在现在 63+1 位时代是可用的没错,但你切换栈内存的做法会出问题的。
【 在 ylh1969 的大作中提到: 】
: 这些都由那4个函数操作,它就是操作这个的。
--
修改:hgoldfish FROM 110.84.121.*
FROM 110.84.121.*
不会的 c++20 stackless coroutine 没这个内存管理的问题。
【 在 ylh1969 的大作中提到: 】
: 32位机一样用。
: 包装后的协程库反而难解决这个问题。
--
修改:hgoldfish FROM 110.84.121.*
FROM 110.84.121.*
这是因为你用在自己项目里面可控啊。
如果是第三方开发者,没弄清楚你这个机制,在堆里面引用了栈内存。这时候就容易出事。
所以在 c/c++ 下玩这种栈内存复用是很危险的。
你要是搞 java/python 的栈内存切换倒是没问题。事实上 python-gevent 切换协程的时候,也会切换内存,就是你这个思路。但那是因为人家 python 的栈和 c/c++ 的栈不是一回事。所有对象占用的内存都被 python 给管理起来了才能这样玩。但 c/c++ 不是。
【 在 ylh1969 的大作中提到: 】
: 不会,都调试好了,运行过了,稳定可靠,资源可控。
--
FROM 110.84.121.*
这就是 await 这个语法传染性的问题了。
和内存管理不是一回事。
反正我也不看好 c++20 的协程。但同时也指出你用 ucontext 没问题,只是额外搞的这个栈内存切换是在风险的。
【 在 ylh1969 的大作中提到: 】
: 敢在协程里调用数据库吗?
--
修改:hgoldfish FROM 110.84.121.*
FROM 110.84.121.*
举个例子:
void my_coroutine() {
Task task;
app()->task_manager->register_task(&task);
send_msg_to_remote();
}
你看这上面这段代码。Task 申请在栈里面。它把自己的指针传给了堆里面的 task_manager,所以 task_manager 保留了一个指向栈的指针对吧。
接下来开始进入阻塞的任务 send_msg_to_remote(),此时,协程被切换走。此时 task_manager 里面指向 task 的指针是不是就出问题了?
在 send_msg_to_remote() 没有返回之前,你肯定不会把栈内存给切换回来是吧。此时如果 task_manager 里面有一行代码:
task->finish()
你说会怎么样?
【 在 ylh1969 的大作中提到: 】
: swapcontxt(uc ,tc);
: 把任务从uc切换到tc,假定uc是堆,tc是栈,
: 那就是堆里的栈保存在uc,协程栈在tc,下一次swap就换回来。
: ...................
--
修改:hgoldfish FROM 110.84.121.*
FROM 110.84.121.*
你做的这个和云风那个类似。知乎上面有个分析云风 coroutine 库的系列文章,你可以去看一下。里面有很多分析。
【 在 ylh1969 的大作中提到: 】
: 我做的就是框架,其他用户用我的框架就行。他根本不需要知道什么是协程,什么是栈。
--
修改:hgoldfish FROM 110.84.121.*
FROM 110.84.121.*