去年,我使用了操作系统,在此期间,我使用用户上下文(在头ucontext.h中定义)为项目实现线程调度器(每个线程模拟一个进程)。我正在参加一个讲座,并将讨论用户上下文,我突然意识到,尽管我去年完成了这个项目,但我并不真正理解getcontext系统调用到底做了什么。
手册页 for getcontext声明
将ucp指向的结构初始化为当前活动的上下文。“
它还声明,对于setcontext的参数,如果ucp参数
是通过调用getcontext()获得的,程序执行继续进行,就好像这个调用刚刚返回一样。
好吧,所以我理解。
这就是我困惑的地方。通常情况下,为了执行上下文切换,我们需要初始化ucontext_t结构并交换/设置它:
ucontext_t ucp;
ucontext_t oucp;
getcontext(&ucp);
// Initialize the stack_t struct in the ucontext_t struct
ucp.uc_stack.ss_sp = malloc(STACK_SIZE);
ucp.uc_stack.ss_size = STACK_SIZE;
ucp.uc_stack.ss_flags = 0;
ucp.uc_link = /* some other context, or just NULL */;
// Don't block any signals in this context
sigemptyset(&ucp.uc_sigmask);
// Assume that fn is a function that takes 0 arguments and returns void
makecontext(&ucp, fn, 0);
// Perform the context switch. Function 'fn' will be active now
swapcontext(&oucp, &ucp);
// alternatively: setcontext(&ucp);如果我在较小的程序中省略了getcontext,就不会有什么有趣的事情发生。在更大的程序中,通过用户上下文进行更多的上下文切换,我得到一个分段错误,这个错误只有通过添加getcontext才能解决。
getcontext到底是做什么的?为什么我不能分配一个ucontext_t结构,通过初始化uc_stack和uc_sigmask字段来初始化它,并调用没有getcontext的makecontext?是否有一些getcontext执行的makecontext不执行的必要初始化?
发布于 2013-12-10 09:09:13
我查看了x86/linux体系结构上的ucontext的GNU libc实现,因此,可能存在以下不同的实现。
GNU libc手册指出:
传递给makecontext的ucp参数将通过调用getcontext来初始化。
如果查看glibc/sysdeps/unix/linux/x86/sys/ucontext.h中的mcontext_t,就会看到一个指向浮点状态(fpregset_t fpregs)的指针,该状态在getcontext()中初始化,在setcontext()中再次取消引用。但是,它没有使用makecontext()进行初始化。我对GDB进行了快速测试,在尝试取消引用ucontext_t结构中指向浮点上下文的指针时,在setcontext()中得到了一个分段错误,而getcontext()没有初始化它:
=> 0x00007ff784308c <+44>:fldenv (%rcx)
https://stackoverflow.com/questions/19503925
复制相似问题