Ответ 1
__kernel_vsyscal
- это метод, используемый linux-gate.so(частью ядра Linux) для создания системного вызова с использованием самого быстрого доступного метода, предпочтительно команды sysenter
. Это объясняется Johan Petersson.
У меня есть ядро, которое сильно отличается от тех, которые я обычно получаю - большинство потоков находятся в __kernel_vsyscall():
9 process 11334 0xffffe410 in __kernel_vsyscall ()
8 process 11453 0xffffe410 in __kernel_vsyscall ()
7 process 11454 0xffffe410 in __kernel_vsyscall ()
6 process 11455 0xffffe410 in __kernel_vsyscall ()
5 process 11474 0xffffe410 in __kernel_vsyscall ()
4 process 11475 0xffffe410 in __kernel_vsyscall ()
3 process 11476 0xffffe410 in __kernel_vsyscall ()
2 process 11477 0xffffe410 in __kernel_vsyscall ()
1 process 11323 0x08220782 in MyClass::myfunc ()
Что это значит?
EDIT: В частности, я обычно вижу много потоков в "pthread_cond_wait" и "___newselect_nocancel", и теперь они находятся во втором кадре в каждом потоке - почему это другое ядро?
__kernel_vsyscal
- это метод, используемый linux-gate.so(частью ядра Linux) для создания системного вызова с использованием самого быстрого доступного метода, предпочтительно команды sysenter
. Это объясняется Johan Petersson.
Когда вы делаете системный вызов (например, чтение из файла, разговор с оборудованием, запись в сокеты), вы фактически создаете прерывание. Затем система обрабатывает прерывание в режиме ядра, и ваш вызов возвращается с результатом. В большинстве случаев для вас необычно иметь много потоков в syscall, если вы не делаете блокирующие вызовы, и в этом случае он ожидал.
В частности, это означает, что поток ожидает системный вызов на уровне ядра. Но это (к сожалению, по моим пунктам) уже в названии:)
В дополнение к уже предоставленной хорошей ссылке на объяснение того, что linux-gate.so
, я бы хотел ответить "почему это ядро отличается?". Самые последние (более новые версии, чем 2.5.68) 32-разрядные Linux-системы используют страницу VDSO (aka linux-gate.so.1
), и вскоре начнут работать 64-разрядные системы (64-битный VDSO был представлен в ядре 2.6.24).
Если вы разрабатываете более старую систему или старый glibc, то вы никогда не увидите __kernel_vsyscall()
, потому что ядро вообще не создавало VDSO, или потому что (старый) glibc не использует его даже когда присутствует VDSO.
Как сказал Адам, главной причиной является производительность. См. Эту ссылку для некоторых старых номеров http://lkml.org/lkml/2002/12/9/13.
Если у вас есть ядро с поддержкой vDSO, вы не используете прерывания для запуска системных вызовов, как сказал Стефан, на самом деле это было из-за того, что прерывания становились все медленнее, когда вся информация vDSO была добавлена в ядро.