kib*_*yte 10 c operating-system posix ucontext
我去年使用了操作系统,在此期间我使用用户上下文(在标题中定义ucontext.h)来实现项目的线程调度程序(其中每个线程模拟一个进程).我正在参加一个讲座,并将谈论用户上下文,我刚刚想到,尽管去年完成了这个项目,但我并不真正理解getcontext系统调用究竟是做什么的.
该getcontext状态的手册页"将ucp指向的结构初始化为当前活动的上下文".对于参数setcontext,它还指出"如果ucp参数是用getcontext()创建的,程序执行就会继续,好像刚刚返回了相应的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);
Run Code Online (Sandbox Code Playgroud)
如果我getcontext在较小的程序中省略,没有任何有趣的事情发生 在通过用户上下文进行更多上下文切换的较大程序中,我得到的分段错误只能通过getcontext重新加入来解决.
到底是getcontext做什么的?为什么我不能只分配一个ucontext_t结构,通过初始化uc_stack和uc_sigmask字段来初始化它,并在makecontext没有getcontext?的情况下调用?是否有一些必要的初始化getcontext执行makecontext不执行?
我在x86/linux体系结构上查看了ucontext的GNU libc实现,因此,可能存在以下不适用的不同实现.
在libc中手动GNU指出:
传递给makecontext的ucp参数应该通过调用getcontext来初始化.
如果你看一下glibc/sysdeps/unix/linux/x86/sys/ucontext.h中的mcontext_t,就会有一个指向浮点状态的指针(fpregset_t fpregs),它在getcontext()中初始化,并在setcontext()中再次取消引用.但是,它不是使用makecontext()初始化的.我使用GDB进行了快速测试,当我尝试在未由getcontext()初始化的ucontext_t结构中取消引用指向浮点上下文的指针时,我在setcontext()中得到了一个段错误:
=> 0x00007ffff784308c <+44>:fldenv(%rcx)