C getpid() против syscall(39)?

#c #linux #macos #unix #system-calls

Вопрос:

Я читал, что syscall(39) возвращает текущий идентификатор процесса (pid)

Тогда почему эти 2 программы выводят 2 разных числа?

 int main() {
    long r = syscall(39);
    printf("returned %ldn", r);
    return 0;
}
 

и:

 int main() {
    long r = getpid();
    printf("returned %ldn", r);
    return 0;
}
 

Я запускаю свою программу в clion, и когда я меняю первую строку, я получаю другой результат, что действительно странно.

Запуск кода в ответах, которые я получил (в macos):

 returned getpid()=9390 vs. syscall(39)=8340
 

что действительно странно.

В ubuntu у меня один и тот же pid для обоих, почему это так?

Комментарии:

1. Какой конкретный результат вы наблюдаете от каждого из них?

2. В какой среде они работают?

3. Почему вы ожидаете, что они будут возвращать одно и то же число при каждом вызове ? Разные запуски одной и той же программы обычно получают разные идентификаторы PID.

4. Идентификатор процесса присваивается операционной системой при запуске программы. Разные запуски одной и той же программы могут иметь разные идентификаторы процессов, как и разные запуски разных программ.

5. Почему бы просто не распечатать оба в одной и той же программе/запустить…?!?

Ответ №1:

Выполнение системных вызовов по их номеру не будет переносимым.

Действительно, мы видим, что 39-это getpid в Linux, но getppid («получить родительский pid») в macOS.

getpid на macOS это 20.

Так вот почему вы видите разные результаты между getpid() macOS и syscall(39) на macOS.

Обратите внимание, что macOS, будучи производным ядра BSD, никоим образом не связан с Linux. Этого не может быть, так как это закрытый исходный код.

Комментарии:

1. Просто любопытно — где вы нашли это сопоставление системных вызовов? Я видел только эту страницу, на которой показано, что 39-это getpid на mac opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/…

2. @GandhiGandhi ваш источник в порядке, он также говорит, что 39-это getppid, а не getpid.

3. @rustyx, возможно, стоит упомянуть о существовании SYS_foobar определений.

4. Ага, хитрый двойной п… @джон, это правильный ответ.

Ответ №2:

Здесь отсутствует одна ключевая деталь-каждый раз, когда вы запускаете программу, ваша ОС присваивает ей новый PID. Вызов одной и той же программы дважды подряд, скорее всего, вернет разные идентификаторы PID, поэтому то, что вы описываете, не является хорошим способом проверить разницу между getpid() и syscall(39) .

Вот лучшая программа для сравнения двух, которая вызывает обе функции в одной и той же программе.

 #include <sys/syscall.h>
#include <stdio.h>

int main() {
    long pid1 = getpid();
    long pid2 = syscall(39);
    printf("returned getpid()=%ld vs. syscall(39)=%ldn", pid1, pid2);
    return 0;
}

 

Комментарии:

1. Но когда я меняю свою программу на версию 1, она печатает тот же старый pid1, когда я меняю ее на версию 2, печатается pid2

2. пожалуйста, посмотрите мое обновление, теперь все гораздо яснее

3. Готча — гораздо более ясный вопрос. Я думаю, что основная причина в том, что syscall() это не переносимо между операционными системами, хотя из этих документов opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/… похоже 39 , это также должно быть эквивалентно getpid() на macOS. Можете ли вы снова обновить свой вопрос, указав полный источник, включая #include строки?