2014-11-04 4 views
0

Linux에서 100ms마다 다양한 작업과 계산을 수행하는 백그라운드 사용자 공간 프로그램을 구현하려고합니다. Linux에서 알람 신호를 사용하여이 작업을 수행 할 수 있습니다. 다음 구조는 인터벌 타이머를 구현 한 방법입니다.Linux에서 C++로 로우 오버 헤드 간격 타이머 구현

void timer_handler (int signum){ 
    printf("In timer handler!\n"); 
} 

int main(){ 

    struct sigaction s_action; 
    struct itimerval timer; 

    /* Set Up a Timer */ 
    /* Install timer_handler as the signal handler for SIGVTALRM. */ 
    memset (&s_action, 0, sizeof (s_action)); 
    s_action.sa_handler = &timer_handler; 
    sigaction (SIGVTALRM, &s_action, NULL); 

    /* Timer configuration for 100ms */ 
    timer.it_value.tv_sec = 0; 
    timer.it_value.tv_usec = 100000; 
    timer.it_interval.tv_sec = 0; 
    timer.it_interval.tv_usec = 100000; 

    /* Set up the timer */ 
    setitimer (ITIMER_VIRTUAL, &timer, NULL); 

    while(1); 
} 

그러나이 방법은 무한 루프 때문에 (성능면에서) 최적의 방법이 아닌 것처럼 보입니다. CPU 사용률을 크게 높입니다. 일단 백그라운드에서 실행되기 시작하면 다른 프로그램의 성능이 15 % 나 떨어집니다.

타이머 인터럽트가 발생하지 않으면 잠자기 상태로 유지되는 프로그램을 만드는 것이 이상적입니다. 멀티 스레딩은 선택 사항 인 것 같지만 그 주제에 대해서는 경험이별로 없습니다. 최소한의 오버 헤드로 그러한 프로그램을 구현하는 방법에 대한 제안이나 조언을 주시면 감사하겠습니다.

+1

프로그램을 잠자기 상태로 만들려면 sleep()을 호출하지 않는 이유는 무엇입니까? –

+0

나는 실제로자는 것을 시도했다. 그러나 일하지 않았다. sleep() 또는 nanosleep()을 사용하면 타이머 핸들러가 실행되지 않습니다. sleep()이 SIGALRM 신호를 방해 할 수있는 alarm (2) 맨 페이지를 읽었습니다. – jake

답변

0

time(7), signal(7), timerfd_create(2), poll(2), nanosleep(2)Advanced Linux Programming 읽어보십시오.

신호 처리기가 올바르지 않습니다 (printf을 호출하면 안됨, write).

당신은

while(1) poll(NULL, 0, 1); 

을 가질 수 있지만, 아마도 timerfd_create로 초기화 된 파일 기술자에 poll을 사용하여 실제 이벤트 루프를 더해야한다.

물론 모든 정규 작업이 해당 기간보다 훨씬 짧다고 확신합니다. (예를 들면, 각 태스크는 50 밀리 초를 초과하지 않고 100 밀리 초 기간을 갖는다).

+1

내 문제는 주로 플래그 (ITIMER_VIRTUAL)로 인해 setitimer와 함께 사용되었다고 생각합니다.이 프로세스는 활성 상태 일 때만 카운트합니다. ITIMER_REAL로 바꾸고 NULL 파일 설명자를 폴링하면 100ms 간격으로 매우 낮은 오버 헤드가 발생합니다. 참조에도 많은 도움을 주셔서 감사합니다. – jake