Лекция 1 Введение в системное программное обеспечение
![]()
|
СобытиеВ информатике и программировании событие — это сообщение программного обеспечения, которое указывает, что произошло. Поток данныхУ этого термина существуют и другие значения, см. Поток. Не следует путать с термином «Многопоточность». Поток данных (англ. stream) в программировании — абстракция, используемая, для чтения или записи файлов, сокетов и т.д. в одинаковой манере. Потоки являются удобным унифицированным программным интерфейсом для чтения или записи файлов (в том числе специальных, в частности связанных с устройством), сокетов и передачи данных между процессами. Поддержка потоков включена в большинство языков программирования и едва ли не во все современные (на 2008 год) операционные системы. При запуске процесса ему предоставляются предопределённые стандартные потоки. Возможность перенаправления потоков позволяет связывать различные программы, и придаёт системе гибкость, являющуюся частью философии Unix. Поток данных в программированииАбстракция потока особенно важна в языке программирования Си, где он представляет из себя источник ввода и/или вывода данных, обычно байтов, связанный с файлом, устройством либо другим процессом. Работа с потоками перенесена во многие другие языки; C++: Iostream из cтандартной библиотеки шаблонов Языки платформы .NET Framework (например, C#): Base Class Library, пространство имен System.IO Поток данных в операционных системахКомандная оболочка UNIX интенсивно использует абстракцию потока для совместного выполнения нескольких утилит. См. такжеСтандартные потоки Враппер Именованный канал Семафор (информатика)Это статья о методе синхронизации выполняющихся одновременно программ. Остальные значения этого слова описаны в статье Семафор. Семафо́р — объект, позволяющий войти в заданный участок кода не более чем n потокам. Определение введено Э. Дейкстрой. Определение семафораСемафор — это объект, с которым можно выполнить три операции. init(n): счётчик := n enter(): ждать пока счётчик не примет значение больше 0; после этого уменьшить счётчик на единицу. leave(): увеличить счётчик на единицу. Предположим, что есть такой участок кода: semaphore.init(5); ..... ..... semaphore.enter(); DoSomething(); semaphore.leave(); Тогда не более пяти потоков могут одновременно выполнять функцию DoSomething(). В более сложных семафорах может использоваться очередь; при этом потоки, ожидающие освобождения семафора, будут проходить через семафор именно в том порядке, в котором они вызывали enter(). Применение семафоровВот некоторые из проблем, которые могут решать семафоры. запрет одновременного выполнения заданных участков кода; поочерёдный доступ к критическому ресурсу (важному ресурсу, для которого невозможен одновременный доступ). Следующий пример показывает, как наладить поочерёдный доступ к консоли. semaphore.init(1); Поток 1: semaphore.enter(); cout << "Состояние массива: "; for (int i=0; i cout << a[i] << ' '; cout << '\n'; semaphore.leave(); Поток 2: semaphore.enter(); cout << "Нажато Esc.\n"; semaphore.leave(); Этот код поможет предотвратить появление листинга наподобие Состояние массива: 1 2 3 Нажато Esc. 4 5 6 (см. также Состояние гонки) Проблемы семафоровВо-первых, пользователь может сделать «утечку семафора», вызвав enter() и забыв вызвать leave(). Реже встречаются ошибки, когда пользователь дважды вызывает leave(). Во-вторых, семафоры чреваты взаимной блокировкой потоков. В частности, опасен такой код: Поток 1: semaphore1.enter(); semaphore2.enter(); ... semaphore2.leave(); semaphore1.leave(); Поток 2: semaphore2.enter(); semaphore1.enter(); ... semaphore1.leave(); semaphore2.leave(); В-третьих, остаётся проблема синхронизации процедур самого семафора. Например, возможна следующая ситуация: два процесса ждут освобождения семафора. После того, как семафор освободился, первый процесс «узнаёт» об этом, но не успевает увеличить счётчик, как управление передаётся второму процессу. Второй процесс тоже узнаёт об освобождении семафора, увеличивает счётчик и входит в защищённый участок кода. Тут управление передаётся первому процессу, тот ещё раз увеличивает счётчик и тоже входит в защищённый участок кода. В итоге имеем превышение разрешённого числа процессов. Данная проблема не имеет алгоритмического решения. Она разрешается либо размещением процедуры ожидания в критической секции, в которой не разрешается переключение с процесса на процесс, либо программистскими приёмами наподобие осуществления проверки флага и его увеличения с помощью одной машинной команды. См. такжеКритическая секция Мьютекс Фьютекс Внешние ссылкиПример реализации семафора с политикой FIFO в Microsoft.NET |