如何使用swapcontext()恢复执行函数(不再重新启动)?

时间:2017-02-18 02:40:47

标签: c multithreading signals scheduler context-switch

我正在构建一个先发制人的用户空间线程调度程序,它使用计时器来中断线程并根据优先级在它们之间切换。但是,一旦线程中断,我似乎无法让它完成;只能重新开始。使用swapcontext我甚至可能要求什么?这段代码的结果应该允许itake5seconds()完成,只是一遍又一遍地循环“Hello”消息。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <ucontext.h>

static ucontext_t mainc, newthread;

void itake5seconds()
{
    puts("Hello. I take 5 seconds to run.");
    sleep(5);
    puts("And I'm done! Wasn't that nice?");
}

void timer_handler(int signum)
{
    puts("Doing some scheduler stuff.");
    swapcontext(&mainc, &newthread);
}

int main(int argc, char* argv[])
{
    struct sigaction sa;

    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = &timer_handler;
    sigaction(SIGALRM, &sa, NULL);

    getcontext(&newthread);
    newthread.uc_stack.ss_sp = malloc(5000);
    newthread.uc_stack.ss_size = 5000;
    newthread.uc_link = &mainc;
    makecontext(&newthread, &itake5seconds, 0);

    struct itimerval timer;
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_usec = 500000;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = 500000;

    setitimer(ITIMER_REAL, &timer, NULL);

    while(1);

    return 0;
}

2 个答案:

答案 0 :(得分:0)

您的代码在信号处理程序(swapcontext)中调用“不安全”函数。因此,程序的行为是“未定义的”。

来自man 7 signal

  

信号处理函数必须非常小心,因为其他地方的处理可能会在程序执行的某个任意点中断。 POSIX具有“安全功能”的概念。如果信号中断了不安全函数的执行,并且处理程序调用了不安全的函数,那么程序的行为是未定义的。

有关如何使用信号处理程序处理此问题的示例,请参阅Complete Context Control中的“SVID上下文处理示例”部分。但基本上你使用volatile int全局变量来标记你的信号处理程序被调用,而是从正常代码执行swapcontext调用(即不在信号处理的上下文中运行的代码)。

答案 1 :(得分:0)

问题是我没有保存swapcontext()返回其第一个参数的当前执行上下文。