2017-02-18 16 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