2009-08-10 8 views
5

Мне было интересно, как scanf()/printf() работает на уровне оборудования и ОС. Где происходит поток данных и что именно делает ОС в это время? Какие вызовы делает ОС? И так далее ...Как работает scanf() внутри ОС?

+2

О какой ОС вы говорите? –

+0

Нуждается в дополнительной информации, – rahul

+0

Я не смотрю ни на какую конкретную ОС. Типы Linux/Unix были бы прекрасны. Я просто хочу получить базовое представление о ситуации. – jetru

ответ

20

scanf() и printf() являются функциями в libc (стандартная библиотека C), и они вызывают системные вызовы read() и write() соответственно, разговаривая с файловыми дескрипторами stdin и stdout соответственно (fscanf и fprintf позволяет указать поток файлов, который вы хотите прочитать/записать).

Вызовы для чтения() и записи() (и всех системных вызовов) приводят к «переключению контекста» из вашего пользовательского приложения в режим ядра, что означает, что он может выполнять привилегированные операции, например, разговаривать напрямую с оборудованием , В зависимости от того, как вы запускали приложение, дескрипторы файлов «stdin» и «stdout», вероятно, связаны с консольным устройством (например, tty0) или каким-то виртуальным консольным устройством (например, с помощью xterm). read() и write() безопасно копировать данные в/из буфера ядра, называемого «uio».

Преобразование части строки в формате scanf и printf не происходит в режиме ядра, но только в обычном режиме пользователя (внутри «libc») общее правило большого пальца с syscalls - это переход в режим ядра так же редко, как и возможно, как избежать служебных издержек при переключении контекста, так и для обеспечения безопасности (вам нужно быть очень осторожным во всем, что происходит в режиме ядра! меньше кода в режиме ядра означает меньше ошибок/уязвимостей в операционной системе).

btw .. все это было написано с точки зрения unix, я не знаю, как работает MS Windows.

+0

Переключатель контекста звучит медленно, если он читает каждый байт по отдельности. Конечно, в наши дни это не имеет большого значения, но мне просто интересно узнать, правильно ли я в этом понимании. –

+1

Системные вызовы чтения и записи берут несколько байтов для передачи через UIO в качестве параметров, поэтому для каждого отдельного байта не требуется отдельный системный вызов. Вы также считаете, что для более простых функций ввода, таких как getchar(), для каждого символа должен быть отдельный вызов, но на самом деле в эти дни libc немного умнее, чем тот, и он поддерживает буфер (внутри libc). Таким образом, он может избежать накладных расходов на производительность при переключении контекста, заполнив его буфер, а затем обработать бит каждый раз, когда вы getchar() или scanf(), до тех пор, пока буфер не будет пуст, и только затем выполните другой системный вызов. –

+0

На тему «это не имеет большого значения в этот день возраст», на самом деле вы были бы удивлены тем, насколько значительным было бы изменение системных вызовов на производительность. Рассмотрим, что syscalls * не менее * в 10 раз медленнее обычного вызова функции. Например, если у вас есть буфер размером 1024 байта, вы делаете только 1/1024 столько системных вызовов.Написание C-реализации команды «cp» с буфером и без него - отличный пример, я отправлю его через несколько минут. –

0

Я думаю, что ОС просто предоставляет два потока: один для ввода, а другой для вывода, потоки абстрактно, как выводятся выходные данные или откуда поступают входные данные.

так что scanf & printf просто добавляют байты (или потребляют байты) из обоих потоков.

+0

Это абстракция высокого уровня. Я хочу узнать подробности о том, как эти потоки работают с оборудованием и как ОС управляет всеми данными. – jetru

1

В моей ОС я работаю с scanf и printf основаны на функциях getch() ant putch().

+0

Ничего себе, это было что-то. Мне удалось изменить вывод с uart на TCP/IP при подключении одного клиента. Это был простой неперехваченный кооперативный микроядро для встроенной системы. –

 Смежные вопросы

  • Нет связанных вопросов^_^