gpt4 book ai didi

可以在 Linux 的用户空间中实现 native 代码的抢占式多任务处理吗?

转载 作者:IT王子 更新时间:2023-10-29 00:37:07 25 4
gpt4 key购买 nike

我想知道是否有可能在 Linux 用户空间的单个进程中实现 native 代码的抢占式多任务处理。 (也就是说,在外部暂停一些正在运行的 native 代码,保存上下文,在不同的上下文中交换,然后恢复执行,所有这些都由用户空间编排但使用可能进入内核的调用。)我认为这可以使用信号来完成SIGALRM*context() 系列的处理程序,但事实证明整个 *context() 系列是 async-signal-unsafe所以这种方法不能保证有效。我确实找到了 gist它实现了这个想法,所以显然它确实碰巧在 Linux 上工作,至少有时是这样,即使 POSIX 不需要它工作。要点将其安装为 SIGALRM 上的信号处理程序,这会进行多次 *context() 调用:

void
timer_interrupt(int j, siginfo_t *si, void *old_context)
{
/* Create new scheduler context */
getcontext(&signal_context);
signal_context.uc_stack.ss_sp = signal_stack;
signal_context.uc_stack.ss_size = STACKSIZE;
signal_context.uc_stack.ss_flags = 0;
sigemptyset(&signal_context.uc_sigmask);
makecontext(&signal_context, scheduler, 1);

/* save running thread, jump to scheduler */
swapcontext(cur_context,&signal_context);
}

Linux 是否提供使这种方法正确的任何保证?有没有办法使这个正确?是否有完全不同的方法来正确执行此操作?

(“在用户空间实现”并不是说我们永远不会进入内核。我的意思是与内核实现的抢占式多任务处理形成对比。)

最佳答案

您无法可靠地更改信号处理程序中的上下文。 (如果您从某个信号处理程序执行此操作,它通常在实践中会起作用,但并非总是如此,因此它是 undefined behavior )。

您可以在信号处理程序(参见 sig_atomic_tsignal(7)signal-safety(7) ...)中设置一些 volatile sig_atomic_t 标志(阅读 sigreturn(2))并检查该标志 < em>定期(例如,至少每几毫秒一次)在您的代码中,例如在大多数调用之前,或在您的 event loop 中如果你有一个,等等......所以它变成了合作用户空间调度。

如果您可以更改代码,则更容易做到,例如当您设计一些发出 C 代码(common practice)的编译器时,或者如果您破解您的 C 编译器以发出此类测试。然后,您将更改代码生成器,有时会在生成的代码中发出这样的测试。

您可能希望禁止阻塞 系统调用并将它们替换为non-blocking变体或包装器。另见 poll(2) , fcntl(2)使用 F_SETFLO_NONBLOCK 等...

您可能希望代码生成器避免大的调用堆栈,例如像 GCC 的 -fsplit-stack instrumentation option确实(阅读 GCC 中的 splitstacks)。

如果您生成(或编写一些)汇编程序,您可以使用这些技巧。据我所知,Go 编译器为其 goroutines 使用了类似的东西。研究你的ABI ,例如来自 here .

但是,内核启动的抢占式调度更可取(在 Linux 上仍会在进程或内核任务之间发生,请参阅 clone(2))。

附言。如果您对使用类似技巧的垃圾收集技术感兴趣,请查看 MPSCheney on the MTA (例如进入 Chicken Scheme )。

关于可以在 Linux 的用户空间中实现 native 代码的抢占式多任务处理吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48123215/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com