【问题标题】:What does the getcontext system call (ucontext.h) really do?getcontext 系统调用 (ucontext.h) 究竟做了什么?
【发布时间】:2013-10-21 20:20:18
【问题描述】:

我去年学习了操作系统,在此期间,我使用用户上下文(在标题 ucontext.h 中定义)为项目实现线程调度程序(其中每个线程模拟一个进程)。我正在参加一个讲座,将讨论用户上下文,我突然想到,尽管去年完成了这个项目,但我并不真正了解 getcontext 系统调用究竟做了什么。

getcontextman pages 声明它

将 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_stackuc_sigmask 字段来初始化它,然后在没有getcontext 的情况下调用makecontext?是否有一些getcontext 执行而makecontext 不执行的必要初始化?

【问题讨论】:

    标签: c operating-system posix ucontext


    【解决方案1】:

    我查看了 x86/linux 架构上 ucontext 的 GNU libc 实现,因此,可能存在以下不适用的不同实现。

    GNU libc manual 声明:

    传递给 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 : fldenv (%rcx)

    【讨论】:

      猜你喜欢
      • 2011-05-09
      • 2012-07-23
      • 2016-09-10
      • 2023-03-15
      • 2012-10-17
      • 2021-06-04
      • 1970-01-01
      • 2018-07-30
      • 2019-10-06
      相关资源
      最近更新 更多