작업이 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-인터럽트가 발생하지 않습니다.
누군가 이유를 설명할 수 있나요? 스케줄러는 그 사이에 일부 상태 변경을 수행합니까?
감사해요.