Термины: Ввод-вывод данных синхронный и асинхронный. Синхронный и асинхронный ввод-вывод Асинхронный ввод вывод

Как известно, имеются два основных режима ввода/вывода: режим обмена с опросом готовности устройства ввода/вывода и режим обмена с прерываниями.

В режиме обмена с опросом готовности управление вводом/выводом осуществляет центральный процессор. Центральный процессор посылает устройству управления команду выполнить некоторое действие устройству ввода/вывода. Последнее исполняет команду, транслируя сигналы, понятные центральному устройству и устройству управления в сигналы, понятные устройству ввода/вывода. Но быстродействие устройства ввода/вывода намного меньше быстродействия центрального процессора. Поэтому сигнал готовности приходится очень долго ожидать, постоянно опрашивая соответствующую линию интерфейса на наличие или отсутствие нужного сигнала. Посылать новую команду, не дождавшись сигнала готовности, сообщающего об исполнении предыдущей команды, бессмысленно. В режиме опроса готовности драйвер, управляющий процессом обмена данными с внешним устройством, как раз и выполняет в цикле команду «проверить наличие сигнала готовности». До тех пор пока сигнал готовности не появится, драйвер ничего другого не делает. При этом, естественно, нерационально используется время центрального процессора. Гораздо выгоднее, выдав команду ввода/ вывода, на время забыть об устройстве ввода/вывода и перейти на выполнение другой программы. А появление сигнала готовности трактовать как запрос на прерывание от устройства ввода/вывода. Именно эти сигналы готовности и являются сигналами запроса на прерывание.

Режим обмена с прерываниями по своей сути является режимом асинхронного управления. Для того чтобы не потерять связь с устройством может быть запущен отсчет времени, в течение которого устройство обязательно должно выполнить команду и выдать сигнал запроса на прерывание. Максимальный интервал времени, и течение которого устройство ввода/вывода или его контроллер должны выдать сигнал запроса на прерывание, часто называют уставной тайм-аута. Если это время истекло после выдачи устройству очередной команды, а устройство так и не ответило, то делается вывод о том, что связь с устройством потеряна и управлять им больше нет возможности. Пользователь и/или задача получают соответствующее диагностическое сообщение.

Рис. 4.1. Управление вводом/выводом

Драйверы. работающие в режиме прерываний, представляют собой сложный комплекс программных модулей и могу г иметь несколько секций: секцию запуска, одну или несколько секций продолжения и секцию завершения.

Секция запуска инициирует операцию ввода/вывода. Эта секция запускается для включения устройства ввода/вывода либо просто для инициации очередной операции ввода/вывода.

Секция продолжения (их может быть несколько, если алгоритм управления обменом данными сложный и требуется несколько прерываний для выполнения одной логической операции) осуществляет основную работу по передаче данных. Секция продолжения, собственно говоря, и является основным обработчиком прерывания. Используемый интерфейс может потребовать для управления вводом/выводом несколько последовательностей управляющих команд, а сигнал прерывания у устройства, как правило, только один. Поэтому после выполнения очередной секции прерывания супервизор прерываний при следующем сигнале готовности должен передать управление другой секции. Это делается за счет изменения адреса обработки прерывания после выполнения очередной секции, если же имеется только одна секция прерываний, то она сама передает управление тому или иному модулю обработки.

Секция завершения обычно выключает устройство ввода/вывода либо просто завершает операцию.

Операция ввода-вывода может выполняться по отношению к программному модулю, запросившему операцию, в синхронном или асинхронном режимах. Смысл этих режимов тот же, что и для рассмотренных выше системных вызовов, - синхронный режим означает, что программный модуль приостанавливает свою работу до тех пор, пока операция ввода-вывода не будет завершена, а при асинхронном режиме программный модуль продолжает выполняться в мультипрограммном режиме одновременно с операцией ввода-вывода. Отличие же заключается в том, что операция ввода-вывода может быть инициирована не только пользовательским процессом - в этом случае операция выполняется в рамках системного вызова, но и кодом ядра, например кодом подсистемы виртуальной памяти для считывания отсутствующей в памяти страницы.

Рис. 7.1. Два режима выполнения операций ввода-вывода

Подсистема ввода-вывода должна предоставлять своим клиентам (пользовательским процессам и кодам ядра) возможность выполнять как синхронные, так и асинхронные операции ввода-вывода, в зависимости от потребностей вызывающей стороны. Системные вызовы ввода-вывода чаще оформляются как синхронные процедуры в связи с тем, что такие операции длятся долго и пользовательскому процессу или потоку все равно придется ждать получения результатов операции для того, чтобы продолжить свою работу. Внутренние же вызовы операций ввода-вывода из модулей ядра обычно выполняются в виде асинхронных процедур, так как кодам ядра нужна свобода в выборе дальнейшего поведения после запроса операции ввода-вывода. Использование асинхронных процедур приводит к более гибким решениям, так как на основе асинхронного вызова всегда можно построить синхронный, создав дополнительную промежуточную процедуру, блокирующую выполнение вызвавшей процедуры до момента завершения ввода-вывода. Иногда и прикладному процессу требуется выполнить асинхронную операцию ввода-вывода, например при микроядерной архитектуре, когда часть кода работает в пользовательском режиме как прикладной процесс, но выполняет функции операционной системы, требующие полной свободы действий и после вызова операции ввода-вывода.

Задача, выдавшая запрос на операцию ввода/вывода, переводится супервизором в состояние ожидания завершения заказанной операции. Когда супервизор получает от секции завершения сообщение о том, что операция завершилась, он переводит задачу в состояние готовности к выполнению, и она продолжает свою работу. Эта ситуация соответствует синхронному вводу/выводу. Синхронный ввод/вывод является стандартным для большинства ОС. Чтобы увеличить ско­рость выполнения приложений, было предложено при необходимости использо­вать асинхронный ввод/вывод.

Простейшим вариантом асинхронного вывода является так называемый буфери­рованный вывод данных на внешнее устройство, при котором данные из приложения передаются не непосредственно на устройство ввода/вывода, а в специальный системный буфер. В этом случае логически операция вывода для приложения считается выполненной сразу же, и задача может не ожидать окон­чания действительного процесса передачи данных на устройство. Процессом реального вывода данных из системного буфера занимается супервизор ввода/ вывода. Естественно, что выделением буфера из системной области памяти за­нимается специальный системный процесс по указанию супервизора ввода/вы­вода. Итак, для рассмотренного случая вывод будет асинхронным, если, во-пер­вых, в запросе на ввод/вывод было указано на необходимость буферирования данных, а во-вторых, если устройство ввода/вывода допускает такие асинхрон­ные операции и это отмечено в UCB. Можно организовать и асинхронный ввод данных. Однако для этого необходи­мо не только выделить область памяти для временного хранения считываемых с устройства данных и связать выделенный буфер с задачей, заказавшей опера­цию, но и сам запрос на операцию ввода/вывода разбить на две части (на два за­проса). В первом запросе указывается операция на считывание данных, подобно тому, как это делается при синхронном вводе/выводе. Однако тип (код) запроса используется другой, и в запросе указывается ещё по крайней мере один допол­нительный параметр – имя (код) того системного объекта, которое получает за­дача в ответ на запрос и которое идентифицирует выделенный буфер. Получив имя буфера (будем этот системный объект условно называть таким образом, хотя в различных ОС для его обозначения используются и другие термины, на­пример – класс), задача продолжает свою работу. Здесь очень важно подчерк­нуть, что в результате запроса на асинхронный ввод данных задача не переводится супервизором ввода/вывода в состояние ожидания завершения операции ввода/ вывода, а остается в состоянии выполнения или в состоянии готовности к вы­полнению. Через некоторое время, выполнив необходимый код, который был оп­ределен программистом, задача выдаёт второй запрос на завершение операции ввода/вывода. В этом втором запросе к тому же устройству, который, естествен­но, имеет другой код (или имя запроса), задача указывает имя системного объек­та (буфера для асинхронного ввода данных) и в случае успешного завершения операции считывания данных тут же получает их из системного буфера. Если же данные ещё не успели до конца переписаться с внешнего устройства в систем­ный буфер, супервизор ввода/вывода переводит задачу в состояние ожидания завершения операции ввода/вывода, и далее всё напоминает обычный синхрон­ный ввод данных.

Обычно асинхронный ввод/вывод предоставляется в большинстве мультипрограммных ОС, особенно если ОС поддерживает мультизадачность с помощью механизма тредов. Однако если асинхронный ввод/вывод в явном виде отсутст­вует, его идеи можно реализовать самому, организовав для вывода данных самостоятельный поток.

Аппаратуру ввода/вывода можно рассматривать как совокупность аппаратурных процессоров , которые способны работать параллельно относительно друг друга, а также относительно центрального процессора (процессоров). На таких «процессорах» выполняются так называемыевнешние процессы. Например, для внешнего устройства (устройства ввода/вывода) внешний процесс может представлять собой совокупность операций, обеспечивающих перевод печатающей головки, продвижение бумаги на одну позицию, смену цвета чернил или печать каких-то символов. Внешние процессы, используя аппаратуру ввода/вывода, взаимодействуют как между собой, так и с обычными «программными» процессами, выполняющимися на центральном процессоре. Важным при этом является то обстоятельство, что скорости выполнения внешних процессов будут существенно (порой, на порядок или больше) отличаться от скорости выполнения обычных («внутренних ») процессов. Для своей нормальной работы внешние и внутрен­ние процессы обязательно должны синхронизироваться. Для сглаживания эф­фекта сильного несоответствия скоростей между внутренними и внешними процессами используют упомянутое выше буферирование. Таким образом, можно говорить о системе параллельных взаимодействующих процессов (см. главу 6).

Буферы являются критическим ресурсом в отношении внутренних (программных) и внешних процессов, которые при параллельном своем развитии информационно взаимодействуют. Через буфер (буферы) данные либо посылаются от некоторого процесса к адресуемому внешнему (операция вывода данных на внешнее устройство), либо от внешнего процесса передаются некоторому программному процессу (операция считывания данных). Введение буферирования как средства информационного взаимодействия выдвигает проблему управле­ния этими системными буферами, которая решается средствами супервизорной части ОС. При этом на супервизор возлагаются задачи не только по выделению и освобождению буферов в системной области памяти, но и синхронизации про­цессов в соответствии с состоянием операций по заполнению или освобождению буферов, а также их ожидания, если свободных буферов в наличии нет, а запрос на ввод/вывод требует буферирования. Обычно супервизор ввода/вывода для решения перечисленных задач использует стандартные средства синхронизации, принятые в данной ОС. Поэтому если ОС имеет развитые средства для решения проблем параллельного выполнения взаимодействующих приложений и задач, то, как правило, она реализует и асинхронный ввод/вывод.

Мы ждали его слишком долго

Что может быть глупее, чем ждать?

Б. Гребенщиков

В ходе этой лекции вы изучите

    Использование системного вызова select

    Использование системного вызова poll

    Некоторые аспекты использования select/pollв многопоточных программах

    Стандартные средства асинхронного ввода/вывода

Системный вызов select

Если ваша программа главным образом занимается операциями ввода/вывода, вы можете получить наиболее важные из преимуществ многопоточности в однопоточной программе, используя системный вызов select(3C). В большинствеUnix-системselectявляется системным вызовом, или, во всяком случае, описывается в секции системного руководства 2 (системные вызовы), т.е. ссылка на него должна была бы выглядеть какselect(2), но вSolaris10 соответствующая страница системного руководства размещена в секции 3C(стандартная библиотека языка С).

Устройства ввода/вывода обычно работают гораздо медленнее центрального процессора, поэтому при выполнении операций с ними процессор обычно оказывается вынужден ждать их. Поэтому во всех ОС системные вызовы синхронного ввода/вывода представляют собой блокирующиеся операции.

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

Если ваша программа работает с несколькими устройствами ввода/вывода и/или сетевыми соединениями, ей невыгодно блокироваться на операции, связанной с одним из этих устройств, ведь в таком состоянии она может пропустить возможность совершить ввод/вывод с другого устройства без блокировки. Эту проблему можно решать при помощи создания нитей, работающих с различными устройствами. В предыдущих лекциях мы изучили все необходимое для разработки таких программ. Однако для решения этой проблемы есть и другие средства.

Системный вызов select(3C) позволяет ожидать готовности нескольких устройств или сетевых соединений (в действительности, готовности объектов большинства типов, которые могут быть идентифицированы файловым дескриптором). Когда один или несколько из дескрипторов оказываются готовы передать данные,select(3C) возвращает управление программе и передает списки готовых дескрипторов в выходных параметрах.

В качестве параметров select(3C) использует множества (наборы) дескрипторов. В старыхUnix-системах множества были реализованы в виде 1024-разрядных битовых масок. В современныхUnix-системах и в других ОС, реализующихselect, множества реализованы в виде непрозрачного типаfd_set, над которым определены некоторые теоретико-множественные операции, а именно – очистка множества, включение дескриптора в множество, исключение дескриптора из множества и проверка наличия дескриптора в множестве. Препроцессорные директивы для выполнения этих операций описаны на странице руководстваselect(3C).

В 32-разрядных версиях UnixSVR4, в том числе вSolaris,fd_setпо прежнему представляет собой 1024-битовую маску; в 64-разрядных версияхSVR4 это маска разрядности 65536 бит. Размер маски определяет не только максимальное количество файловых дескрипторов в наборе, но и максимальный номер файлового дескриптора в наборе. Размер маски в вашей версии системы можно определить во время компиляции по значению препроцессорного символаFD_SETSIZE. Нумерация файловых дескрипторов вUnixначинается с 0, поэтому максимальный номер дескриптора равенFD_SETSIZE-1.

Таким образом, если вы используете select(3C), вам необходимо установить ограничения на количество дескрипторов вашего процесса. Это может быть сделано шелловской командойulimit(1) перед запуском процесса или системным вызовомsetrlimit(2) уже во время исполнения вашего процесса. Разумеется,setrlimit(2) необходимо вызвать до того, как вы начнете создавать файловые дескрипторы.

Если вам необходимо использовать более 1024 дескрипторов в 32-битной программе, Solaris10 предоставляет переходныйAPI. Для его использования необходимо определить

препроцессорный символ FD_SETSIZEс числовым значением, превышающим 1024, перед включением файла . При этом в файле сработают необходимые препроцессорные директивы и типfd_setбудет определен как большая битовая маска, аselectи другие системные вызовы этого семейства будут переопределены для использования масок такого размера.

В некоторых реализациях fd_setреализован другими средствами, без использования битовых масок. Например,Win32 предоставляетselectв составе так называемогоWinsockAPI. ВWin32fd_setреализован как динамический массив, содержащий значения файловых дескрипторов. Поэтому вам не следует полагаться на знание внутренней структуры типаfd_set.

Так или иначе, изменения размера битовой маски fd_setили внутреннего представления этого типа требуют перекомпиляции всех программ, использующихselect(3C). В будущем, когда архитектурный лимит в 65536 дескрипторов на процесс будет повышен, может потребоваться новая версия реализацииfd_setиselectи новая перекомпиляция программ. Чтобы избежать этого и упростить переход на новую версиюABI, компанияSunMicrosystemsрекомендует отказываться от использованияselect(3C) и использовать вместо него системный вызовpoll(2). Системный вызовpoll(2) рассматривается далее на этой лекции.

Системный вызов select(3C) имеет пять параметров.

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

fd_set*readfds– Входной параметр, множество дескрипторов, которые следует проверять на готовность к чтению. Конец файла или закрытие сокета считается частным случаем готовности к чтению. Регулярные файлы всегда считаются готовыми к чтению. Также, если вы хотите проверить слушающий сокетTCPна готовность к выполнениюaccept(3SOCKET), его следует включить в это множество. Также, выходной параметр, множество дескрипторов, готовых к чтению.

fd_set*writefds– Входной параметр, множество дескрипторов, которые следует проверять на готовность к записи. Ошибка при отложенной записи считается частным случаем готовности к записи. Регулярные файлы всегда готовы к записи. Также, если вы хотите проверить завершение операции асинхронногоconnect(3SOCKET), сокет следует включить в это множество. Также, выходной параметр, множество дескрипторов, готовых к записи.

fd_set*errorfds– Входной параметр, множество дескрипторов, которые следует проверять на наличие исключительных состояний. Определение исключительного состояния зависит от типа файлового дескриптора. Для сокетовTCPисключительное состояние возникает при приходе внеполосных данных. Регулярные файлы всегда считаются находящимися в исключительном состоянии. Также, выходной параметр, множество дескрипторов, на которых возникли исключительные состояния.

structtimeval*timeout– тайм-аут, временной интервал, задаваемый с точностью до микросекунд. Если этот параметр равенNULL, тоselect(3C) будет ожидать неограниченное время; если в структуре задан нулевой интервал времени,select(3C) работает в режиме опроса, то есть возвращает управление немедленно, возможно с пустыми наборами дескрипторов.

Вместо всех параметров типа fd_set* можно передать нулевой указатель. Это означает, что соответствующий класс событий нас не интересует.select(3C) возвращает общее количество готовых дескрипторов во всех множествах при нормальном завершении (в том числе при завершении по тайм-ауту), и -1 при ошибке.

В примере 1 приводится использование select(3C) для копирования данных из сетевого соединения на терминал, а с терминала – в сетевое соединение. Эта программа упрощенная, она предполагает, что запись на терминал и в сетевое соединение никогда не будет заблокирована. Поскольку и терминал, и сетевое соединение имеют внутренние буферы, при небольших потоках данных это обычно так и есть.

Пример 1. Двустороннее копирование данных между терминалом и сетевым соединением. Пример взят из книги У.Р. Стивенс, Unix: разработка сетевых приложений. Вместо стандартных системных вызовов используются «обертки», описанные в файле “unp.h”

#include "unp.h"

void str_cli(FILE *fp, int sockfd) {

int maxfdp1, stdineof;

char sendline, recvline;

if (stdineof == 0) FD_SET(fileno(fp), &rset);

FD_SET(sockfd, &rset);

maxfdp1 = max(fileno(fp), sockfd) + 1;

Select(maxfdp1, &rset, NULL, NULL, NULL);

if (FD_ISSET(sockfd, &rset)) { /* socket is readable */

if (Readline(sockfd, recvline, MAXLINE) == 0) {

if (stdineof == 1) return; /* normal termination */

else err_quit("str_cli: server terminated prematurely");

Fputs(recvline, stdout);

if (FD_ISSET(fileno(fp), &rset)) { /* input is readable */

if (Fgets(sendline, MAXLINE, fp) == NULL) {

Shutdown(sockfd, SHUT_WR); /* send FIN */

FD_CLR(fileno(fp), &rset);

Writen(sockfd, sendline, strlen(sendline));

Обратите внимание, что программа примера 1 заново пересоздает множества дескрипторов перед каждым вызовом select(3C). Это необходимо, потому что при нормальном завершенииselect(3C) модифицирует свои параметры.

select(3C) считаетсяMT-Safe, однако при его использовании в многопоточной программе надо иметь в виду следующий момент. Действительно, сам по себеselect(3C) не использует локальных данных и поэтому его вызов из нескольких нитей не должен приводить к проблемам. Однако если несколько нитей работают с пересекающимися наборами файловых дескрипторов, возможен такой сценарий:

    Нить 1 вызывает readиз дескриптораsи получает все данные из его буфера

    Нить 2 вызывает readиз дескриптораsи блокируется.

Чтобы избежать этого сценария, работу с файловыми дескрипторами в таких условиях следует защищать мутексами или какими-то другими примитивами взаимоисключения. Важно подчеркнуть, что защищать надо не select, а именно последовательность операций над конкретным файловым дескриптором, начиная с включения дескриптора в множество дляselectи заканчивая приемом данных из этого дескриптора, точнее, обновлением указателей в буфере, в который вы считали эти данные. Если этого не сделать, возможны еще более увлекательные сценарии, например:

    Нить 1 включает дескриптор sв наборreadfdsи вызываетselect.

    selectв нити 1 возвращаетsкак готовый для чтения

    Нить 2 включает дескриптор sв наборreadfdsи вызываетselect

    selectв нити 2 возвращаетsкак готовый для чтения

    Нить 1 вызывает readиз дескриптораsи получает только часть данных из его буфера

    Нить 2 вызывает readиз дескриптораs, получает данные и записывает их поверх данных, полученных нитью 1

В лекции 10 мы рассмотрим архитектуру приложения, в котором несколько нитей работают с общим пулом файловых дескрипторов – так называемую архитектуру рабочих нитей (workerthreads). При этом нити, разумеется, должны указывать друг другу, с какими именно дескрипторами они сейчас работают.

С точки зрения разработки многопоточных программ, важным недостатком select(3C) – или, возможно, недостаткомPOSIXThreadAPI– является тот факт, что примитивы синхронизацииPOSIXне являются файловыми дескрипторами и не могут использоваться вselect(3C). В то же время, при реальной разработке многопоточных программ, занимающихся вводом/выводом, часто было бы полезно ожидать в одной операции готовности файловых дескрипторов и готовности других нитей собственного процесса.

Асинхронный ввод/вывод сиспользованием нескольких потоков

Перекрывающийся и расширенный ввод/вывод позволяют добиться асинхронного выполнения операций ввода/вывода в пределах единственного потока, хотя для поддержки этой функциональности ОС создает собственные потоки. В том или ином виде методы этого типа часто используются во многих ранних ОС для поддержки ограниченных форм выполнения асинхронных операций в однопоточных системах.

Однако Windows обеспечивает многопоточную поддержку, поэтому становится возможным достижение того же эффекта за счет выполнения синхронных операций ввода/вывода в нескольких, выполняемых независимо потоках. Ранее эти возможности уже были продемонстрированы на примере многопоточных серверов и программы grepMT (глава 7). Кроме того, потоки обеспечивают концептуально последовательный и, предположительно, гораздо более простой способ выполнения асинхронных операций ввода/вывода. В качестве альтернативы методам, используемым в программах 14.1 и 14.2, можно было бы предоставить каждому потоку собственный дескриптор файла, и тогда каждый из потоков мог бы обрабатывать в синхронном режиме каждую четвертую запись.

Такой способ использования потоков продемонстрирован в программе atouMT, которая в книге не приводится, но включена в материал, размещенный на Web-сайте. Программа atouMT не только способна выполняться под управлением любой версии Windows, но и более проста по сравнению с любым из двух вариантов программ асинхронного ввода/вывода, поскольку учет использования ресурсов в этом случае менее сложен. Каждый поток просто поддерживает собственные буферы в собственном стеке и выполняет в цикле последовательность синхронных операций чтения, преобразования и записи. При этом производительность программы остается на достаточно высоком уровне.

Примечание

В программе atouMT.с, которая находится на Web-сайте, содержатся комментарии по поводу нескольких возможных "ловушек", которые могут поджидать вас при организации доступа одновременно нескольких потоков к одному и тому же файлу. В частности, все отдельные дескрипторы файлов должны создаваться с помощью функции CreateHandle, а не функции DuplicateHandle.

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

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

Из книги Давайте создадим компилятор! автора Креншоу Джек

Из книги Программирование на языке Пролог автора Клоксин У.

Из книги Язык программирования С# 2005 и платформа.NET 2.0. автора Троелсен Эндрю

Из книги Руководство администратора баз данных Informix. автора Кустов Виктор

Из книги Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT автора Фролов Александр Вячеславович

2.2.3.2 Асинхронный ввод-вывод Для ускорения операций ввода-вывода сервер использует собственный пакет асинхронного ввода-вывода (AIO) или пакет асинхронного ввода-вывода ядра ОС (KAIO), если он доступен. Пользовательские запросы на ввод-вывод обрабатываются асинхронно,

Из книги Основы объектно-ориентированного программирования автора Мейер Бертран

Ввод/вывод Как вы знаете, операторы << и >> выполняют сдвиг числового значения влево и вправо на опеределенное число бит. В программах, приведенных в нашей книге, эти операторы также используются для ввода информации с клавиатуры и вывода на экран.Если с левой стороны

Из книги Системное программирование в среде Windows автора Харт Джонсон М

Ввод и вывод Два класса библиотеки KERNEL обеспечивают основные средства ввода и вывода: FILE и STD_FILES.Среди операций, определенных для объекта f типа FILE, есть следующие:create f.make ("name") -- Связывает f с файлом по имени name.f.open_write -- Открытие f для записиf.open_read -- Открытие f для

Из книги Программирование на языке Ruby [Идеология языка, теория и практика применения] автора Фултон Хэл

ГЛАВА 14 Асинхронный ввод/вывод и порты завершения Операциям ввода и вывода присуща более медленная скорость выполнения по сравнению с другими видами обработки. Причиной такого замедления являются следующие факторы: Задержки, обусловленные затратами времени на поиск

Из книги Программирование на языке Пролог для искусственного интеллекта автора Братко Иван

10.1.7. Простой ввод/вывод Вы уже знакомы с некоторыми методами ввода/вывода из модуля Kernel; мы вызывали их без указания вызывающего объекта. К ним относятся функции gets и puts, а также print, printf и p (последний вызывает метод объекта inspect, чтобы распечатать его в понятном для нас

Из книги Язык программирования Си для персонального компьютера автора Бочков C. О.

Из книги Linux программирование в примерах автора Роббинс Арнольд

Глава 6 Ввод и вывод В этой главе мы рассмотрим некоторые встроенные средства для записи данных в файл и считывания их из файла. Такие средства можно также применять и для форматирования объектов данных программы, чтобы получить желаемую форму их внешнего представления.

Из книги Основы программирования на Java автора Сухов С. А.

Ввод и вывод Функции ввода и вывода в стандартной библиотеке Си позволяют читать данные из файлов или получать их с устройств ввода (например, с клавиатуры) и записывать данные в файлы, или выводить их на различные устройства (например, на принтер).Функции ввода/вывода

Из книги QT 4: программирование GUI на С++ автора Бланшет Жасмин

4.4. Ввод и вывод Все операции Linux по вводу/выводу осуществляются посредством дескрипторов файлов. Данный раздел знакомит с дескрипторами файлов, описывает, как их получать и освобождать, и объясняет, как выполнять с их помощью

Из книги Идеальный программист. Как стать профессионалом разработки ПО автора Мартин Роберт С.

Из книги автора

Глава 12. Ввод-вывод Почти в каждом приложении приходится читать или записывать файлы или выполнять другие операции ввода-вывода. Qt обеспечивает великолепную поддержку ввода-вывода при помощи QIODevice - мощной абстракции «устройств», способных читать и записывать

Из книги автора

Ввод и вывод Также мне кажется очень важным, чтобы мои результаты подпитывались соответствующим «вводом». Написание программного кода – творческая работа. Обычно мои творческие способности в наибольшей степени проявляются тогда, когда я сталкиваюсь с творческим