备注

此机制的最早版本是setjmp(3)/ longjmp(3)机制。由于这并未定义对信号上下文的处理,因此下一阶段是sigsetjmp(3)/ siglongjmp(3)对。本机制提供了更多的控制。另一方面,没有简单的方法来检测从getcontext()返回的是第一次调用还是通过setcontext()调用。用户必须发明自己的簿记设备,并且由于恢复了寄存器,所以不会使用寄存器变量。

发生信号时,内核会保存当前用户上下文,并为信号处理程序创建一个新的上下文。不要使用longjmp(3)离开处理程序:这是不确定的,上下文会发生什么。请改用siglongjmp(3)或setcontext()。

说明

在类似于System V的环境中,其中一个具有定义的两种类型mcontext_t和ucontext_t,以及四个函数getcontext(),setcontext(),makecontext(3)和swapcontext(3),它们允许在多个线程之间进行用户级上下文切换。在一个过程中的控制。

mcontext_t类型是机器相关的且不透明。 ucontext_t类型是至少具有以下字段的结构:

typedef struct ucontext_t {
    struct ucontext_t *uc_link;
    sigset_t          uc_sigmask;
    stack_t           uc_stack;
    mcontext_t        uc_mcontext;
    ...
} ucontext_t;

在中定义了sigset_t和stack_t。此处uc_link指向当前上下文终止时将恢复的上下文(如果使用makecontext(3)创建当前上下文),则uc_sigmask是在此上下文中被阻止的信号集(请参见sigprocmask(2)),uc_stack是此上下文使用的堆栈(请参见sigaltstack(2)),而uc_mcontext是保存的上下文的特定于机器的表示形式,其中包括调用线程的机器寄存器。

函数getcontext()将ucp指向的结构初始化为当前活动的上下文。

函数setcontext()恢复ucp指向的用户上下文。成功的呼叫不会返回。该上下文应已通过调用getcontext()或makecontext(3)获得,或作为第三个参数传递给信号处理程序。

如果上下文是通过调用getcontext()获得的,则程序执行将继续,就像该调用刚刚返回一样。

如果上下文是通过调用makecontext(3)获得的,则通过调用函数func来继续执行程序,该函数指定为对makecontext(3)的调用的第二个参数。当函数func返回时,我们继续将ucp结构的uc_link成员指定为该makecontext(3)调用的第一个参数。当此成员为NULL时,线程退出。

如果上下文是通过对信号处理程序的调用获得的,则旧的标准文本会指出"程序的执行在信号中断的指令之后继续执行程序指令"。但是,这句话在SUSv2中已删除,目前的结论是"结果不确定"。

遵循规范

SUSv2,POSIX.1-2001。 POSIX.1-2008删除了getcontext()的规范,理由是可移植性问题,并建议改写应用程序以使用POSIX线程。

GETCONTEXT - Linux手册页

Linux程序员手册 第3部分
更新日期: 2017-09-15

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

错误说明

没有定义。

名称

getcontext,setcontext-获取或设置用户上下文

属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
getcontext(),setcontext()Thread safetyMT-Safe race:ucp

语法

#包括

int getcontext(ucontext_t * ucp);
int setcontext(const ucontext_t * ucp);

返回值

成功时,getcontext()返回0,而setcontext()不返回。错误时,都返回-1并适当设置errno。

另外参见

sigaction(2),sigaltstack(2),sigprocmask(2),longjmp(3),makecontext(3),sigsetjmp(3)

日期:2019-08-20 18:00:26 来源:oir作者:oir