2017-02-18 72 views
0

我正在構建一個先發制人的用戶空間線程調度器,它使用一個定時器來中斷線程並根據優先級在它們之間切換。但是,一旦線程中斷,我似乎無法完成;只能再次啓動它。我甚至有可能使用swapcontext?這個代碼的結果應該允許itake5seconds()完成,只是反覆循環「Hello」消息。如何使用swapcontext()恢復執行一個函數(而不是再次啓動)?

#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; 
} 

回答

0

您的代碼正在調用信號處理函數(swapcontext)中的「不安全」函數。因此,你的程序的行爲是「未定義的」。

man 7 signal

的信號處理函數必須非常小心,因爲在別處處理可以在該程序的執行某任意點被中斷。 POSIX具有「安全功能」的概念。如果信號中斷不安全函數的執行,並且處理程序調用不安全的函數,那麼程序的行爲是不確定的。

請參閱Complete Context Control中的「SVID上下文處理示例」一節,瞭解如何使用信號處理程序進行處理。但基本上你會使用一個volatile int全局變量來標記你的信號處理程序被調用,而不是從正常的代碼(即在信號處理的上下文中沒有運行的代碼)調用swapcontext

0

問題是我沒有保存swapcontext()返回到它的第一個參數的當前執行上下文。

+0

你能提供更新後的代碼給大家看嗎? – Mike

相關問題