タスクが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スレッドがブロックされたくないので、フラグを設定するときに意図的にミューテックスを使用しません。したがって、バーがいくつかの覚醒を見逃しても構いません。とにかくループのために時々目を覚ますでしょう。金持ち。ここでの目標は、次の状態を確認することです。プハーバー仕事、今もっと興味を持ってくださいバー。 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が常に何であるかを観察してください。D(ノンストップ)。コードを見ると、コンテキスト切り替えは、条件変数がスリープモードのとき、またはタイムスライスが完了したときにのみ発生する可能性があります(CFSスケジューラで実行中)。
cat /proc/30295/task/30296/wchan
futex_wait_queue_me
文書によると、これは割り込み可能な機能です。 proc でジョブの状態を複数回確認すると常に表示されます。S:
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-割り込みは発生しません。
誰かが理由を説明できますか?スケジューラはその間にいくつかの状態変更を実行しますか?
ありがとうございます。