2012-06-25 6 views
3

단일 프로세서 시나리오를 고려해 봅시다.조건이 충족 될 때까지 대기열 구현이 루프에서 대기하는 이유는 무엇입니까?

wait_event_interruptible() (또는 다른 대기 API)은 특정 조건이 충족 될 때까지 루프에서 대기합니다.

리눅스는 별도의 프로세스로 구현 된 스레드를 가지고 있기 때문에 거짓 웨이크가 발생합니다 (여기서 은 조건이 충족되지 않아 깨우침을받습니다)는 프로그램/드라이버의 오류를 나타냅니다.

내가 틀렸어? - 그러한 거짓 후류가 일어날 수 있고 사용되는 유효한 시나리오가 있습니까? 즉, 루프wait_event* 구현에서 조건을 기다리는 이유는 무엇입니까?

답변

7

대기열의 일반적인 사용 예는 인터럽트입니다. 아마도 커널 드라이버가 세 가지 조건을 기다리고있을 것입니다. 각각의 상황은 인터럽트로 인해 깨우쳐 질 것입니다.

이렇게하면 커널 인터럽트 처리기가 모든 청취자를 깨우고 특정 조건이 발생했는지 또는 깨어 있어야 하는지를 스스로 결정할 수 있습니다.

또한 인터럽트를 공유 할 수 있고 인터럽트가 지연되어 병합되기 때문에 가짜 인터럽트를 얻을 수 있습니다.


일부 코드를 추가하면 더 명확하게하려고하지 않을 수 있습니다.

커널 드라이버에 포함될 수있는 코드를 아래에 작성했습니다. 인터럽트 처리기는 모든 리스너를 깨울뿐입니다. 그러나 모든 청취자가 실제로 수행 될 수있는 것은 아닙니다. 둘 다 똑같은 인터럽트에 의해 깨우쳐 질 것이나, 계속하기 전에 그들의 특별한 상태가 끝났는지보기 위해 둘 다 보일 것이다.

// Registered interrupt handler 
static irqreturn_t interrupt_handler(void *private) { 
    struct device_handle *handle = private; 
    wake_up_all(&handle->wait); 
} 

// Some Kernel Thread 
void program_a(struct device_handle * handle) { 
    wait_event_interruptible(&handle->wait, hardware_register & 0x1); 
    printk("program_a finished\n"); 
} 

// Some other kernel thread 
void program_b(struct device_handle * handle) { 
    wait_event_interruptible(&handle->wait, hardware_register & 0x2); 
    printk("program_b finished\n"); 
} 
+0

드라이버가 여러 조건에서 대기 할 수 있습니까?처음 대기 때문에 프로세스가 일시 중단되면 다른 프로세스는 실행할 수 없습니까? 그래서 나는 하나의 기다림이있을 수 있다고 생각합니까? – Chethan

+0

몇 가지 코드를 추가했습니다. 그러나 커널 모듈은 한 시점에서 여러 스레드를 실행할 수 있습니다. –

0

단일 프로세서 시나리오에서도 커널은 선점 형입니다. 즉, 제어가 다른 스레드/프로세스로 전달 될 수 있으므로 동작이 다중 프로세서와 동일합니다. 잃어버린-대기 문제에 좋은 논의는 여기에 있습니다 : http://www.linuxjournal.com/node/8144/print

+0

제어가 통과 할 수 있다고 동의합니다. 그러나 'wait_event'의 루프가이 기사에서 설명한 동기화 문제를 해결하는 방법을 알지 못합니다. 루프는 재시도 시도보다 더 많은 것 같습니다. 이유를 알고 싶습니다. – Chethan

3

코드 :

#define __wait_event(wq, condition)      \ 
do {         \ 
    DEFINE_WAIT(__wait);      \ 
            \ 
    for (;;) {       \ 
     prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); \ 
     if (condition)      \ 
      break;      \ 
     schedule();      \ 
    }        \ 
    finish_wait(&wq, &__wait);     \ 
} while (0) 

내가 가정 (커널이 ... 선제 사실 외에) 당신이

을 참조하고 위의 무한 루프 'for'에? 그렇다면 주된 이유는 다음과 같습니다.

코드는 일단 깨우면 상태에 대한 어떤 가정도하지 않습니다. 잠에서 깨어 나면 이 아니라은 실제로 기다렸던 이벤트를 의미합니다. 너 이어야한다. 이것이 바로 루프가 달성 한 것입니다. 'if'조건이 충족되면 (정상적인 경우) 루프를 종료하고 그렇지 않으면 (가짜 wakeup) schedule()을 호출하여 다시 절전 상태가됩니다.

관련 문제