/proc/pid/stat의 Linux 작업 상태가 예약된 이벤트의 Ftrace 출력과 다릅니다.

/proc/pid/stat의 Linux 작업 상태가 예약된 이벤트의 Ftrace 출력과 다릅니다.

작업이 D/S/R 상태(무중단/중단 가능/실행 중)에 들어가는 지점을 이해하기 위해 코드 조각의 흐름을 추적하려고 합니다. 각 상태가 무엇을 의미하는지 이해하지만, 연습을 실행하면 혼란스러운 결과가 나타났고 지금까지는 그 이유를 알 수 없었습니다.

내가 실행 중인 코드 조각:

void foo() {

    pthread_setname_np(pthread_self(), "lock_func/1");

    while(quit == false)
    {
        for(int64_t idx=0; idx<10000000;idx++)
            (void)idx;
        flag = true;
        cv1.notify_all();
    }
}

void bar() {

    pthread_setname_np(pthread_self(), "lock_func/2");
    std::mutex mutex1;
    std::unique_lock<std::mutex> lock(mutex1);
    while(!flag)
        cv1.wait(lock);
    flag = false;
}

int main(int argc, char *argv[]) {

    ...
    std::thread t1 = std::thread(foo);
    std::thread t2 = std::thread(bar);
    ...
    if (mlockall( MCL_CURRENT | MCL_FUTURE ) < 0) { 
        perror("mlockall") 
    }
    ....   
}

foo 스레드가 차단되는 것을 원하지 않기 때문에 플래그를 설정할 때 의도적으로 뮤텍스를 사용하지 않습니다. 따라서 bar가 일부 깨우기를 놓치더라도 상관하지 않습니다. 어쨌든 루프로 인해 때때로 깨어날 것입니다.부자. 여기서 목표는 다음 상태를 확인하는 것입니다.푸허 바작업, 이제 더 많은 관심을 가져보세요술집. ftrace에서 sched_switch 이벤트를 추적하면 다음과 같은 결과가 나타납니다.

      <idle>-0     [007] d...       335998: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120
 lock_func/1-30296 [007] d...       335999: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120
      <idle>-0     [007] d...       336000: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120
 lock_func/1-30296 [007] d...       336001: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120
      <idle>-0     [007] d...       336002: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120
 lock_func/1-30296 [007] d...       336003: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120
      <idle>-0     [007] d...       336004: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120
 lock_func/1-30296 [007] d...       336005: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120
      <idle>-0     [007] d...       336006: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120
 lock_func/1-30296 [007] d...       336007: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120
      <idle>-0     [007] d...       336008: sched_switch: prev_comm=swapper/7 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120
 lock_func/1-30296 [007] d...       336009: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120
      <idle>-0     [000] d...       336010: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120
 lock_func/1-30296 [000] d...       336011: sched_switch: prev_comm=lock_func/1 prev_pid=30296 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
      <idle>-0     [000] d...       336012: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=lock_func/1 next_pid=30296 next_prio=120

내 lock_func1(bar)의 prev_state가 항상 어떤지 관찰하세요.(논스톱). 코드를 보면 컨텍스트 전환은 조건 변수가 절전 모드일 때 또는 타임 슬라이스가 완료될 때만 발생할 수 있습니다(CFS 스케줄러에서 실행 중).

cat /proc/30295/task/30296/wchan
futex_wait_queue_me

문서에 따르면 이는 인터럽트 가능한 기능입니다. proc에서 작업 상태를 여러 번 확인하면 항상 표시됩니다.에스:

cat /proc/30295/task/30296/stat
30295 (lock_func/1) S ...

따라서 통계에는 S-인터럽트 가능 상태가 표시됩니다.futex_wait_queue_me중단 가능하지만 ftrace는 항상 컨텍스트 스위치에 표시됩니다.이전 상태=D. 이 코드를 실행하고 몇 초 동안 ftrace로 로깅하면 다음과 같은 결과만 표시됩니다.이전 상태=D내 lock_func/1(bar)에 대해. S-인터럽트가 발생하지 않습니다.

누군가 이유를 설명할 수 있나요? 스케줄러는 그 사이에 일부 상태 변경을 수행합니까?

감사해요.

관련 정보