2013-10-12 3 views
3

리눅스 커널이 어떻게 작동하는지에 대한 일반적인 아이디어를 얻으려면 "Robert Love의 제 3 판"을 읽는 중입니다. (2.6.2.3)리눅스 커널 대기 대기

큐 예를 들어이 코드를 작동 기다립니다

/* ‘q’ is the wait queue we wish to sleep on */ 
DEFINE_WAIT(wait); 
add_wait_queue(q, &wait); 

while (!condition) { /* condition is the event that we are waiting for */ 
    prepare_to_wait(&q, &wait, TASK_INTERRUPTIBLE); 
    if (signal_pending(current)) 
     /* handle signal */ 
     schedule(); 
    } 

finish_wait(&q, &wait); 
  • 는이 코드를 실행중인 프로세스를 알고 싶어? 커널 스레드입니까? 누구의 프로세스 시간이 이것입니까?

  • 또한 조건이 여전히 충족되지 않는 동안 우리는 다른 프로세스를 실행하기 위해 수면 및 호출 일정을 계속 수행합니다 질문은 언제이 루프로 돌아갈 수 있습니까?

  • 이 책은 ... 프로세스가 절전 모드로 전환되는시기, 그것은 다른 사람이 그것을 깨울 바쁜 루프를 입력해야 할 것입니다, 우리의 실행 큐에서 제거 된 것을 말한다

  • 또한 말한다

    : "수면은 항상에서 처리해야한다 작업이 대기중인 조건이 실제로 발생했는지 확인하는 루프입니다. "

이 루프가 실행중인 컨텍스트가 무엇인지 알고 싶습니다.

죄송합니다. 이것이 바보 같은 질문 인 경우입니다. 큰 그림을 보는 데 문제가 있습니다.

답변

6

코드를 실행하는 프로세스는 무엇입니까? 그것을 부르는 과정. 질문을 재미있게 만드는 것을 의미하지는 않지만 요지는 커널 코드가 다른 컨텍스트에서 실행될 수 있다는 것입니다. 시스템 호출이이 장소로 인도되었거나 인터럽트 처리기에 있기 때문에 또는 호출 된 콜백 함수이기 때문에 (예 : 작업 대기열 또는 타이머 기능).

이 예제는 절전 모드이므로 절전 모드가 허용되는 컨텍스트에 있어야합니다. 즉, 시스템 호출이나 적어도 커널 스레드에 대한 응답으로 실행됩니다. 따라서 응답은 프로세스 시간 (또는 커널 스레드)에서 잠을 자야하는이 커널 코드를 호출 한 시간입니다. 그 곳에서자는 것이 허용되는 유일한 장소입니다.

특수한 경우는 작업 대기열입니다. 이는 잠자기해야하는 기능을 명시 적으로 나타냅니다. 일반적인 사용은 수면이 금지 된 상황에서 잠을 자야하는 함수를 대기열에 넣는 것입니다. 이 경우 프로세스 컨텍스트는 작업 큐 항목을 처리하도록 지정된 커널 작업자 스레드 중 하나의 프로세스 컨텍스트입니다.

wait_queue가 깨어 났을 때이 루프로 돌아가며 호출 된 wake_up 함수에 따라 대기열에서 대기중인 작업 하나 또는 모두를 실행 가능으로 설정합니다.

가장 중요한 것은 구현 세부 정보에 관심이 없으면 잊어 버리는 것입니다. 많은 사람들이 이것을 잘못 이해했기 때문에 기본적으로 모든 곳에서 동일한 절차가 필요합니다. 오랫동안 매크로가 전체 절차를 캡슐화했습니다. ... ... 내가 의견을 추가하여 예를 당으로

wait_event(q, condition); 
+0

안녕하세요! 위대한 첫 번째 대답! –

+0

고마워, @ 브라이언 케인! –

+1

이것은 스케줄러의 일부가 아니며 (_calling_ schedule()임을 알 수 있습니다.) 자신을 잠자기 상태로 만듭니다. 이것은 조건이 충족 될 때까지 wait_queue에서 대기하는 표준 코드이므로 wait_event()에 캡슐화 된 표준입니다. 이것은 커널 선점보다 오래된 것입니다. –

1

참고 : 그 당신의 예를 정말 좋아 보일 것입니다 방법) ((interruptible이없는) wait_queue를 봐 기본적으로 큐를 기다리는 만드는 동안이됩니다 수면 상태에 있어야한다.

DEFINE_WAIT (대기);/* 첫 번째 대기 ---> 대기중인 커널 대기 대기열 */

add_wait_queue (q, & 대기);/* 첫 번째 대기 ---> 커널 전역 대기 대기열 (add_wait_queue (q, & 대기)); ---> 대기열 대기열을 추가하고 있습니다. (연결된 목록 추가) */

while (! 상태) { /* 대기중인 이벤트 */ /* 조건 - (의 당신은 어떤 wake_up_process() 호출이 인터럽트 */ 경우 (signal_pending을 가지고 생성 될 때 */

prepare_to_wait(&q, &wait, TASK_INTERRUPTIBLE); 

은/*이 기다릴 것이다 (__get_user는()를 사용하여) 쓰기 방식으로 사용자 공간에서 데이터를 받고 있다고 가정 해 봅시다 현재))

/* 이는 현재 CPU에서 신호가 보류 중인지 계속 모니터링합니다 어떤 대기중인 대기열에서 어떤 신호도 보류하지 않는 동안 일반적으로 사용되는 return -ERESTARTSYS; 또는 "휴식"루프는 인터럽트 EXA 온 경우, SIGINT 또는 SIGKILL 및 마감재 다시 / / 핸들 신호 */

schedule(); // Scheduling of wait queue 
       // Remove from global data structure 
} 

finish_wait (& Q, & 대기)를 확인하기 위해 큐 문을 기다립니다.; // 대기 대기 완료

관련 문제