Light-electric.com

IT Журнал
71 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Что такое поток в программировании

Поток (программирование)

Поток ( _en. stream) — абстрактная последовательность инструкций или данных вообще, привязанная к соответствующему дескриптору (может быть представлен именем потока).

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

Поддержка потоков включена в большинство языков программирования и едва ли не во все современные (на 2008 год) операционные системы.

При запуске процесса ему предоставляются предопределённые стандартные потоки.

Возможность перенаправления потоков позволяет связывать различные программы, и придаёт системе гибкость, являющуюся частью философии Unix.

Поток данных в программировании

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

Поток данных в операционных системах

Командная оболочка UNIX интенсивно использует абстракцию потока для совместного выполнения нескольких утилит.

См. также

* Стандартные потоки
* Враппер

Wikimedia Foundation . 2010 .

Смотреть что такое «Поток (программирование)» в других словарях:

Поток выполнения — Для термина «Поток» см. другие значения. Процесс с двумя потоками выполнения на одном процессоре Поток выполнения (анг … Википедия

Поток минимальной стоимости — Задача о потоке минимальной стоимости состоит в нахождении самого дешёвого способа передачи определённого количества потока через транспортную сеть. Содержание 1 Определения 2 Отношение к другим задачам … Википедия

Поток POSIX — POSIX Threads стандарт потоков (нитей) выполнения, определяющий API для создания и управления ими. Библиотеки, реализующие этот стандарт (и функции этого стандарта), обычно называются Pthreads (функции имеют приставку «pthread »). Хотя наиболее… … Википедия

Линейное программирование — Линейное программирование математическая дисциплина, посвящённая теории и методам решения экстремальных задач на множествах мерного векторного пространства, задаваемых системами линейных уравнений и неравенств. Линейное программирование… … Википедия

Класс (программирование) — У этого термина существуют и другие значения, см. Класс. Класс в программировании набор методов и функций. Другие абстрактные типы данных метаклассы, интерфейсы, структуры, перечисления характеризуются какими то своими, другими… … Википедия

Объектно-ориентированное программирование — Эта статья во многом или полностью опирается на неавторитетные источники. Информация из таких источников не соответствует требованию проверяемости представленной информации, и такие ссылки не показывают значимость темы статьи. Статью можно… … Википедия

Событийно-ориентированное программирование — Парадигмы программирования Агентно ориентированная Компонентно ориентированная Конкатенативная Декларативная (контрастирует с Императивной) Ограничениями Функциональная Потоком данных Таблично ориентированная (электронные таблицы) Реактивная … Википедия

Реактивное программирование — Парадигмы программирования Агентно ориентированная Компонентно ориентированная Конкатенативная Декларативная (контрастирует с Императивной) Ограничениями Функциональная Потоком данных Таблично ориентированная (электронные таблицы) Реактивная … Википедия

Грамотное программирование — Стиль этой статьи неэнциклопедичен или нарушает нормы русского языка. Статью следует исправить согласно стилистическим правилам Википедии … Википедия

Парное программирование — техника программирования, при которой весь исходный код создаётся парами людей, программирующих одну задачу, сидя за одним рабочим местом. Один программист управляет компьютером и, в основном, думает над кодированием в деталях. Другой программист … Википедия

Что такое поток в программировании

Системное программирование

Главная страница

Младший специалист

Бакалавр

О сайте

Дополнительные материалы

Пройти тест

Лекция №13. Потоковый ввод-вывод в стандарте Cи

Под вводом-выводом в программировании понимается процесс обмена информацией между оперативной памятью и внешними устройствами: клавиатурой, дисплеем, магнитными накопителя­ми и т. п. Ввод — это занесение информации с внешних устройств в оперативную память, а вывод — вынос информации из опера­тивной памяти на внешние устройства. Такие устройства, как дис­плей и принтер, предназначены только для вывода; клавиатура — устройство ввода. Магнитные накопители (диски, ленты) исполь­зуются как для ввода, так и для вывода.

Основным понятием, связанным с информацией на внешних устройствах ЭВМ, является понятие файла. Всякая операция вво­да-вывода трактуется как операция обмена с файлами: ввод — это чтение из файла в оперативную память; вывод — запись инфор­мации из оперативной памяти в файл. Поэтому вопрос об органи­зации в языке программирования ввода-вывода сводится к вопро­су об организации работы с файлами.

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

Аналогом понятия внутреннего файла в языках Си/Си++ яв­ляется понятие потока. Поток — это байтовая последовательность, передаваемая в про­цессе ввода-вывода.

Поток должен быть связан с каким-либо внешним устройством или файлом на диске. В терминологии Си это звучит так; поток должен быть направлен на какое-то устройство или файл.

Основные отличия файлов в Си состоят в следующем: здесь отсутствует понятие типа файла и, следовательно, фиксирован­ной структуры записи файла. Любой файл рассматривается как байтовая последовательность:

Стрелочкой обозначен указатель файла, определяющий теку­щий байт файла. EOF является стандартной константой — призна­ком конца файла.

Существуют стандартные потоки и потоки, объявляемые в про­грамме. Последние обычно связываются с файлами на диске, со­здаваемыми программистом. Стандартные потоки назначаются и открываются системой автоматически. С началом работы любой программы открываются 5 стандартных потоков, из которых ос­новными являются следующие:

o stdin — поток стандартного ввода (обычно связан с клавиатурой);

o stdout — поток стандартного вывода (обычно связан с дисплеем);

o stderr — вывод сообщений об ошибках (связан с диспле­ем).

Кроме этого, открывается поток для стандартной печати и до­полнительный поток для последовательного порта.

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

Читать еще:  Net сетевое программирование для профессионалов pdf

Работа с файлами на диске. Работа с дисковым файлом начи­нается с объявления указателя на поток. Формат такого объяв­ления:

Слово file является стандартным именем структурного типа, объявленного в заголовочном файле stdio.h. В структуре file содержится информация, с помощью которой ведется работа с потоком, в частности: указатель на буфер, указатель (индикатор) текущей позиции в потоке и т.д.

Следующий шаг — открытие потока, которое производится с помощью стандартной функции fopen (). Эта функция возвраща­ет конкретное значение для указателя на поток и поэтому ее зна­чение присваивается объявленному ранее указателю. Соответству­ющий оператор имеет формат:

Имя_указателя=fореn (“имя_файла”, “режим_открытия”) ;

Параметры функции fopen () являются строками, которые мо­гут быть как константами, так и указателями на символьные мас­сивы. Например:

Здесь test .dat — это имя физического файла в текущем ката­логе диска, с которым теперь будет связан поток с указателем fр. Параметр режима r означает, что файл открыт для чтения. Что касается терминологии, то допустимо употреблять как выражение «открытие потока», так и выражение «открытие файла».

Существуют следующие режимы открытия потока и соответ­ствующие им параметры:

r открыть для чтения

w создать для записи

а открыть для добавления

r+ открыть для чтения и записи

w+ создать для чтения и записи

а+ открыть для добавления или

создать для чтения и записи

Поток может быть открыт либо для текстового, либо для дво­ичного (бинарного) режима обмена.

Понятие текстового файла: это последовательность символов, которая делится на строки специальными кодами — возврат ка­ретки (код 13) и перевод строки (код 10). Если файл открыт в текстовом режиме, то при чтении из такого файла комбинация символов «возврат каретки — перевод строки» преобразуется в один символ n — переход к новой строке.

При записи в файл осуществляется обратное преобразование. При работе с двоичным файлом никаких преобразований симво­лов не происходит, т.е. информация переносится без всяких из­менений.

Указанные выше параметры режимов открывают текстовые файлы. Если требуется указать на двоичный файл, то к параметру добавляется буква b. Например: rb, или « b », или r +b. В некоторых компиляторах текстовый режим обмена обозначается буквой t, т.е. записывается a+t или rt.

Если при открытии потока по какой-либо причине возникла ошибка, то функция fopen() возвращает значение константы null. Эта константа также определена в файле stdio.h. Ошибка может возникнуть из-за отсутствия открываемого файла на диске, нехватки места в динамической памяти и т.п. Поэтому желатель­но контролировать правильность прохождения процедуры откры­тия файла. Рекомендуется следующий способ открытия:

if (fp=fopen(«test.dat», «r»)==NULL)

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

Закрытие потока (файла) осуществляет функция fclose(), прототип которой имеет вид:

int fclose(FILE *fptr);

Здесь fptr обозначает формальное имя указателя на закрыва­емый поток. Функция возвращает ноль, если операция закрытия прошла успешно. Другая величина означает ошибку.

Запись и чтение символов. Запись символов в поток произво­дится функцией putc() с прототипом

int putc (int ch, FILE *fptr);

Если операция прошла успешно, то возвращается записанный символ. В случае ошибки возвращается константа EOF.

Считывание символа из потока, открытого для чтения, произ­водится функцией gets () с прототипом

int gets (FILE *fptr);

Функция возвращает значение считываемого из файла сим­вола. Если достигнут конец файла, то возвращается значение EOF. Заметим, что это происходит лишь в результате чтения кода EOF.

Исторически сложилось так, что gets() возвращает значение типа int. To же можно сказать и про аргумент ch в описании функции puts(). Используется же в обоих случаях только млад­ший байт. Поэтому обмен при обращении может происходить и с переменными типа char.

Пример 1. Составим программу записи в файл символьной пос­ледовательности, вводимой с клавиатуры. Пусть признаком завер­шения ввода будет символ *.

//Запись символов в файл

puts(«Вводите символы. Признак конца — *»);

В результате на диске (в каталоге, определяемом системой) будет создан файл с именем test.dat, который заполнится вводимы­ми символами. Символ * в файл не запишется.

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

//Чтение символов из файла

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

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

int putw(int, FILE *fptr);

Если операция прошла успешно, то возвращается записанное число. В случае ошибки возвращается константа EOF.

Считывание целого числа из потока, открытого для чтения, производится функцией getw () с прототипом

int getw(FILE *fptr);

Функция возвращает значение считываемого из файла числа. Если прочитан конец файла, то возвращается значение EOF.

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

Урок №207. Потоки ввода и вывода

Обновл. 12 Янв 2020 |

Функционал потоков ввода/вывода не определён как часть языка C++, а предоставляется Стандартной библиотекой C++ (и, следовательно, находится в пространстве имён std). В предыдущих уроках мы подключали заголовочный файл библиотеки iostream и использовали объекты cin и cout для простого ввода/вывода данных. В этом уроке мы рассмотрим библиотеку iostream детальнее.

Библиотека iostream

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

Первое, что вы можете заметить в этой иерархии — множественное наследование (то, что на самом деле не рекомендуется использовать). Тем не менее, библиотека iostream была разработана и тщательно протестирована соответствующим образом, дабы избежать типичных ошибок, которые возникают при работе с множественным наследованием, поэтому вы можете использовать эту библиотеку не боясь.

Читать еще:  Язык программирования c википедия

Потоки в С++

Второе, что вы могли бы заметить — это частое использование слова «stream» (т.е. «поток»). По сути, ввод/вывод в C++ реализован с помощью потоков. Абстрактно, поток — это последовательность символов, к которой можно получить доступ. Со временем поток может производить или потреблять потенциально неограниченные объёмы данных.

Мы будем иметь дело с двумя типами потоков. Поток ввода (или ещё «входной поток») используется для хранения данных, полученных от источника данных: клавиатуры, файла, сети и т.д. Например, пользователь может нажать клавишу на клавиатуре в то время, когда программа не ожидает ввода. Вместо игнорирования нажатия клавиши, данные помещаются во входной поток, где затем ожидают ответа от программы.

И наоборот, поток вывода (или ещё «выходной поток») используется для хранения данных, предоставляемых конкретному потребителю данных: монитору, файлу, принтеру и т.д. При записи данных на устройство вывода, это устройство может быть не готовым принять данные немедленно — например, принтер все ещё может прогреваться, когда программа уже записывает данные в выходной поток. Таким образом, данные будут находиться в потоке вывода до тех пор, пока принтер не начнёт их использовать.

Некоторые устройства, такие как файлы и сети, могут быть источниками как ввода, так и вывода данных.

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

Ввод/вывод в C++

Хотя класс ios является дочерним классу ios_base , очень часто именно этот класс будет наиболее родительским классом, с которым вы будете работать/взаимодействовать напрямую. Класс ios определяет кучу разных вещей, которые являются общими для потоков ввода/вывода.

Класс istream используется для работы с входными потоками. Оператор извлечения >> используется для извлечения значений из потока. Это имеет смысл: когда пользователь нажимает на клавишу клавиатуры, код этой клавиши помещается во входной поток. Затем программа извлекает это значение из потока и использует его.

Класс ostream используется для работы с выходными потоками. Оператор вставки istream , ostream и iostream (соответственно). В большинстве случаев вы не будете работать с ними напрямую.

Стандартные потоки в C++

Стандартный поток — это предварительно подключенный поток, который предоставляется программе её окружением. C++ поставляется с 4-мя предварительно определёнными стандартными объектами потоков, которые вы можете использовать (первые три вы уже встречали):

cin — класс istream_withassign , связанный со стандартным вводом (обычно это клавиатура);

cout — класс ostream_withassign , связанный со стандартным выводом (обычно это монитор);

cerr — класс ostream_withassign , связанный со стандартной ошибкой (обычно это монитор), обеспечивающий небуферизованный вывод;

clog — класс ostream_withassign , связанный со стандартной ошибкой (обычно это монитор), обеспечивающий буферизованный вывод.

Небуферизованный вывод обычно обрабатывается сразу же, тогда как буферизованный вывод обычно сохраняется и выводится как блок. Поскольку clog используется редко, то его обычно игнорируют.

Пример на практике

Вот пример использования ввода/вывода данных со стандартными потоками:

Многопоточность в C

Что такое тема?
Поток — это отдельный поток последовательности внутри процесса. Поскольку потоки имеют некоторые свойства процессов, их иногда называют.

Каковы различия между процессом и потоком?
Потоки не являются независимыми друг от друга, как процессы, в результате потоки делятся с другими потоками своими разделами кода, данными и ресурсами ОС, такими как открытые файлы и сигналы. Но, как и процесс, поток имеет свой собственный программный счетчик (ПК), набор регистров и пространство стека.

Почему многопоточность?
Потоки — это популярный способ улучшить приложение с помощью параллелизма. Например, в браузере несколько вкладок могут быть разными потоками. MS word использует несколько потоков, один поток для форматирования текста, другой поток для обработки ввода и т. Д.
Потоки работают быстрее, чем процессы по следующим причинам:
1) Создание темы намного быстрее.
2) Переключение контекста между потоками происходит намного быстрее.
3) темы могут быть легко прекращены
4) Связь между потоками быстрее.

rmuhamma/OpSystems/Myos/threads.htm для получения более подробной информации.

Можем ли мы написать многопоточные программы на C?
В отличие от Java, многопоточность не поддерживается стандартом языка. POSIX Threads (или Pthreads) — это стандарт POSIX для потоков. Реализация pthread доступна с компилятором gcc.

Простая C-программа для демонстрации использования базовых функций pthread
Обратите внимание, что приведенная ниже программа может компилироваться только с компиляторами C с библиотекой pthread.

#include
#include
#include //Header file for sleep(). man 3 sleep for details.
#include

// Обычная функция C, которая выполняется как поток
// когда его имя указано в pthread_create ()

void *myThreadFun( void *vargp)

printf ( «Printing GeeksQuiz from Thread n» );

printf ( «Before Threadn» );

printf ( «After Threadn» );

В main () мы объявляем переменную с именем thread_id, которая имеет тип pthread_t, который является целым числом, используемым для идентификации потока в системе. После объявления thread_id мы вызываем функцию pthread_create () для создания потока.
pthread_create () принимает 4 аргумента.
Первый аргумент — это указатель на thread_id, который устанавливается этой функцией.
Второй аргумент определяет атрибуты. Если значение равно NULL, то должны использоваться атрибуты по умолчанию.
Третий аргумент — это имя функции, которая должна быть выполнена для создаваемого потока.
Четвертый аргумент используется для передачи аргументов функции, myThreadFun.
Функция pthread_join () для потоков является эквивалентом wait () для процессов. Вызов pthread_join блокирует вызывающий поток, пока поток с идентификатором, равным первому аргументу, не завершится.

Как скомпилировать вышеуказанную программу?
Чтобы скомпилировать многопоточную программу с использованием gcc, нам нужно связать ее с библиотекой pthreads. Ниже приведена команда, используемая для компиляции программы.

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

Читать еще:  Что такое параллельное программирование

#include
#include
#include
#include

// Давайте создадим глобальную переменную, чтобы изменить ее в потоках

// Функция, выполняемая всеми потоками

void *myThreadFun( void *vargp)

// Сохраняем аргумент значения, переданный в этот поток

int *myid = ( int *)vargp;

// Давайте создадим статическую переменную для наблюдения за ее изменениями

static int s = 0;

// Изменить статические и глобальные переменные

// Распечатать аргумент, статические и глобальные переменные

printf ( «Thread ID: %d, Static: %d, Global: %dn» , *myid, ++s, ++g);

Программирование потоков данных

Программирование потоков данных (англ. dataflow programming ) — подход к программированию, при котором программа моделируется в виде ориентированного графа потока данных между операциями, подобного диаграмме потока данных. Развивается в программной инженерии с 1970-х годов [1] .

Естественное визуальное представление наряду с поддержкой параллелизма являются двумя привлекательными для разработчиков свойствами данной парадигмы [1] . Разумеется, программирование потоков данных необязательно сопряжено с инструментами визуального программирования.

Программисты Unix знакомы с программированием потоков данных, так как в командной оболочке этой системы применяются именованные каналы и другие подобные средства межпроцессного взаимодействия [2] .

Содержание

Описание

Основой работы программ потоков данных (dataflow) является активация вычислений на узлах (node), которые можно считать чёрными ящиками, вызываемая изменениями, обновлениями входных данных. Узел (в модели — вершина графа) представляет из себя элемент, который производит обработку данных на входе, преобразуя их в данные на выходе. Работа узла в течение периода активации считается единичным вычислением. Узлы посылают и принимают данные через порты (port) — точки соединения дуг (рёбер графа) и узлов. Порты — всё, что связывает узел с окружением. Для различения узлы могут иметь имена. Результат вычисления узла часто, но не обязательно, является функцией входных данных, то есть, результат может изменяться со временем. Вычислительная работа узла называется активацией (activation, firing). В активированном состоянии узел берёт входные данные, производит вычисления, отдаёт выходные данные в соответствующие порты. Передаваемые данные независимо от их типа называются токенами (token). Токены поступают по дугам (их можно называть рёбрами, связями, соединениями). Появление данных на входящей дуге может вызывать активацию узла. Обычно принято, что в дуге находится не более одного токена, но в теории можно создать и модели с неограниченной ёмкостью. В более разработанных моделях дуги могут сливаться в одну или разветвляться [3] [4] .

В результате программирования получается программа потоков данных — ориентированный граф. Все пути взаимодействия элементов явно задаются программистом. В простейшем случае конвейерной обработки (pipeline dataflow) элементы можно задать последовательностью единичных вычислений. Вычисления производятся по очереди, при поступлении токенов на вход. Такая схема называется выполнением, управляемым данными (data-driven execution [3] ).

Характеристики

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

  • Push- или pull-дисциплины для дуг. В первом случае токены «выталкиваются» по инициативе производителя данных, а во втором инициатором запроса токена является потребитель. Два подхода также известны как вычисление, управляемое данными (data-driven computation) и вычисление, управляемое запросами (demand-driven computation) [4]
  • Изменяемые (mutable) или неизменяемые (immutable) данные. Хотя неизменяемые данные — наиболее удачный подход для параллельной обработки, некоторые реализации, основанные на императивных языках программирования, могут требовать изменяемых данных со всеми необходимыми механизмами синхронизации.
  • Возможности слияния (join) и разветвления (split) дуг. В случае слияния, порт назначения дуги получает токены от любого из двух портов в начале дуги. При разветвлении токен обычно копируется двум получателям. Слияния и разветвления могут быть множественными.
  • Статическая или динамическая программа потока данных. Эта характеристика касается возможности изменений в графе потока данных. Аппаратные реализации, как правило, используют статические программы, но в общем случае структура графа может динамически изменяться. В динамической программе некоторая дуга может изменить порт назначения или узел обработки — свои характеристики.
  • Узел может быть функциональным или же хранить своё состояние (stateful) внутри.
  • Синхронная или асинхронная активация. Один из важнейших параметров классификации систем потоков данных. Синхронная активация подразумевает некоторый заранее зафиксированный и спланированный порядок активации, построенный с учётом всей программы в целом. В системе с асинхронной активацией каждый блок заботится о своём настоящем и активация происходит при удовлетворении условий, например, появлении данных на входе. Для систем с асинхронной активацией могут потребоваться дуги ёмкостью более одного токена. Схема активации может быть и смешанной (hybrid).
  • Множественные входные и выходные порты. Наличие нескольких портов может потребовать и изменения для условий активации. Например, активация может происходить, если хотя бы один из входов получил данные. В более сложных случаях могут использоваться схемы активации (fire pattern), в котором для каждого порта одно из четырёх отношений к активации: 1 — на входе есть данные, 0 — на входе нет данных, X — наличие данных безразлично, * — безусловная активация (независимо от условий для других портов). Узел может иметь несколько схем, которые проверяются одна за другой, пока не схема не будет соответствовать текущему состоянию. Например, трёхпортовый узел со схемой «[1, 1, X], [0, X, 0]» будет активизирован, если первые два порта получили данные или на первом и третьем порту нет данных.
  • Обратные связи, или циклы, позволяют использовать выходной поток снова на входе вычислительного блока. При работе с циклами необходимо избегать тупиковых ситуаций (см. взаимная блокировка), при котором некоторый узел будет ждать данных на входе, которые зависят от его же выхода. Для работы с обратной связью может потребовать задание начальных токенов (ещё до запуска программы) для дуг обратной связи или использование одноразовых узлов (one-shot), которые активируются ровно один раз, в начале работы программы.
  • Составные узлы (compound node) позволяют пакетировать примитивные узлы в более крупные модули.
  • Рекурсивные узлы. Разновидность составного узла, содержащего копию самого себя.
  • Многоскоростное производство и потребление токенов. Для повышения производительности при активации может быть позволено получение и отправка нескольких токенов из порта сразу.
Ссылка на основную публикацию
Adblock
detector