在 linux 下,glibc
提供了几个函数来给用户实现用户态的上下文切换:
getcontext
:初始化一个上下文参数setcontext
:根据参数还原上下文makecontext
:创建一个新的上下文swapcontext
:上下文切换
getcontext 和 setcontext
详细文档:https://linux.die.net/man/3/getcontext
1 |
|
getcontext
: 保存当前上下文到第一个参数setcontext
: 设置当前上下文为第一个参数(成功调用的时候不会返回)。- 如果第一个参数是通过
getcontext
获取的,则调用之后继续往下执行, - 如果是通过
makecontext
创建的,程序会调用makecontext
的第二个参数指向的函数, - 当函数执行完毕,转到
uc_link
指向的上下文,如果uc_link
为null
,则线程退出。
- 如果第一个参数是通过
makecontext
详细文档:https://man7.org/linux/man-pages/man3/swapcontext.3.html
1 |
|
makecontext
: 修改第一个参数为getcontext
之后的ucontext_t
,如getcontext(&uctx); makecontext(&uctx);
swapcontext
: 保存当前上下文到第一个参数,然后切换到第二个参数对应的上下文
ucontext_t.uc_link 在当前上下文结束后的上下文
getcontext 和 setcontext 成功的时候返回 0,失败的时候返回 -1。
注意事项
- OSX 下
ucontext_t
的栈大小要大于等于32Kb
,否则makecontext
调用无效。 context
对应的函数里面需要用到栈的时候,是线程共享的栈,而不是ucontext_t.uc_stack
指定的栈。所以给ucontext_t.uc_stack
设置初始化的栈的时候,不用考虑context
对应函数需要占用多少栈空间。