#24_TOS
ЗАВЕРШЕНИЕ ПРОЦЕССА и КОД ЗАВЕРШЕНИЯ в LINUX.
Процесс может быть завершен двумя способами:
— запросом своего собственного завершения с использованием системного вызова
(или родственной ему библиотечной функции exit( ));
— путем его уничтожения извне с помощью сигнала.
В любом случае процесс выдает код завершения, небольшое неотрицательное целое число, которое может быть проверено родительским процессом с использованием системного вызова
В случае вызова _exit( ) процесс явным образом указывает свой собственный код завершения.
Если процесс уничтожается сигналом, код завершения устанавливается по типу сигнала, уничтожившего процесс.
По соглашению, код завершения 0 служит признаком успешного завершения процесса, а ненулевое значение служит признаком возникновения какой-то ошибки.
Большинство оболочек позволяют получить код завершения последней выполненной программы с помощью переменной оболочки по имени $?.
ЗАВЕРШЕНИЕ ПРОЦЕССА и КОД ЗАВЕРШЕНИЯ в LINUX.
Процесс может быть завершен двумя способами:
— запросом своего собственного завершения с использованием системного вызова
_exit();
(или родственной ему библиотечной функции exit( ));
— путем его уничтожения извне с помощью сигнала.
В любом случае процесс выдает код завершения, небольшое неотрицательное целое число, которое может быть проверено родительским процессом с использованием системного вызова
wait();
В случае вызова _exit( ) процесс явным образом указывает свой собственный код завершения.
Если процесс уничтожается сигналом, код завершения устанавливается по типу сигнала, уничтожившего процесс.
По соглашению, код завершения 0 служит признаком успешного завершения процесса, а ненулевое значение служит признаком возникновения какой-то ошибки.
Большинство оболочек позволяют получить код завершения последней выполненной программы с помощью переменной оболочки по имени $?.
#25_TOS
ПРОЦЕСС INIT в LINUX.
При загрузке системы ядро создает особый процесс, который называется
init — «родитель всех процессов».
Он ведет свое происхождение от программного файла
Все процессы в системе создаются (используя fork()) либо процессом init, либо одним из его потомков.
Процесс init всегда имеет идентификатор процесса 1 и запускается с правами доступа суперпользователя.
Процесс init не может быть уничтожен (даже привилегированным пользователем) и завершается только при завершении работы системы.
Основной задачей init является создание и слежение за процессами, требующимися работающей системе.
ПРОЦЕСС INIT в LINUX.
При загрузке системы ядро создает особый процесс, который называется
init — «родитель всех процессов».
Он ведет свое происхождение от программного файла
/sbin/init.
Все процессы в системе создаются (используя fork()) либо процессом init, либо одним из его потомков.
Процесс init всегда имеет идентификатор процесса 1 и запускается с правами доступа суперпользователя.
Процесс init не может быть уничтожен (даже привилегированным пользователем) и завершается только при завершении работы системы.
Основной задачей init является создание и слежение за процессами, требующимися работающей системе.
#26_TOS
ПРОЦЕССЫ-ДЕМОНЫ в LINUX.
Демон — процесс специального назначения, создаваемый и управляемый системой точно так же, как и другие процессы, но отличающийся от них следующими характеристиками:
— процесс-демон долгоживущий, зачастую запускается при загрузке системы и продолжает свое существование до тех пор, пока работа системы не будет завершена;
— запускается в фоновом режиме, и у него нет управляющего терминала, с которого он мог бы считывать ввод или на который он мог бы записывать вывод.
К примерам процессов-демонов относятся syslogd, который записывает сообщения
в системный журнал, и httpd, который обслуживает веб-страницы посредством протокола передачи гипертекста — Hypertext Transfer Protocol (HTTP).
ПРОЦЕССЫ-ДЕМОНЫ в LINUX.
Демон — процесс специального назначения, создаваемый и управляемый системой точно так же, как и другие процессы, но отличающийся от них следующими характеристиками:
— процесс-демон долгоживущий, зачастую запускается при загрузке системы и продолжает свое существование до тех пор, пока работа системы не будет завершена;
— запускается в фоновом режиме, и у него нет управляющего терминала, с которого он мог бы считывать ввод или на который он мог бы записывать вывод.
К примерам процессов-демонов относятся syslogd, который записывает сообщения
в системный журнал, и httpd, который обслуживает веб-страницы посредством протокола передачи гипертекста — Hypertext Transfer Protocol (HTTP).
#27_Cpp
ПЕРЕГРУЗКА ОПЕРАТОРОВ в С++.
Важно помнить:
перегружаются через методы класса — это требования языка С++.
Унарные операторы:
так же лучше перегружать через методы класса.
Перегрузку бинарных операторов (операторов с двумя операндами), которые изменяют левый операнд:
лучше выполнять через методы класса.
Перегрузку бинарных операторов (операторов с двумя операндами), которые не изменяют левый операнд:
лучше выполнять через обычные или дружественные функции.
Операторы ввода (>>) и вывода (<<)
нельзя перегружать через методы класса потому что они должны возвращать объекты класса std::istream и std::ostream соответственно.
Их перегрузку лучше реализовывать через обычные или дружественные функции.
ПЕРЕГРУЗКА ОПЕРАТОРОВ в С++.
Важно помнить:
operator=( ) — оператор присваивания;
operator[ ]( ) — индекса;
operator()( ) — вызова функции;
operator->( ) — выбора члена;
перегружаются через методы класса — это требования языка С++.
Унарные операторы:
operator+( ); — унарный плюс;
operator-( ); — унарный минус;
bool operator!( ); — оператор логического НЕ.
так же лучше перегружать через методы класса.
Перегрузку бинарных операторов (операторов с двумя операндами), которые изменяют левый операнд:
operator+=( );
operator-=( );
operator*=( );
operator/=( );
operator%=( );
лучше выполнять через методы класса.
Перегрузку бинарных операторов (операторов с двумя операндами), которые не изменяют левый операнд:
operator+( );
operator-( );
operator*( );
operator/( );
operator%( );
лучше выполнять через обычные или дружественные функции.
Операторы ввода (>>) и вывода (<<)
std::istream& operator» (std::istream &in, T& t);
std::ostream& operator« (std::ostream &out, const T& t);
нельзя перегружать через методы класса потому что они должны возвращать объекты класса std::istream и std::ostream соответственно.
Их перегрузку лучше реализовывать через обычные или дружественные функции.
#28_CMPL_DBG_TOS_TP
ELF64 — Executable and Linkable Format 64-bit (выполняемый и связываемый формат для 64 битной системы).
ELF64 — Executable and Linkable Format 64-bit (выполняемый и связываемый формат для 64 битной системы).
#29_CMPL_DBG_TP
DWARF (Debug With Arbitrary Record Format) — отладка с использованием произвольного формата записей.
DWARF (Debug With Arbitrary Record Format) — отладка с использованием произвольного формата записей.
#31_ASM_CMPL_GCC_TP
Последние версии компилятора и линкера GCC по умолчанию генерируют выполняемый код, не зависящий от положения в памяти, или перемещаемый код (position independent executable – PIE).
Это делается для защиты от хакеров, исследующих, как память используется программой, что в итоге позволяет им воздействовать на выполнение программы.
Такая программа слишком сложна для анализа (усложнение делается преднамеренно из соображений обеспечения безопасности).
Ключ компилятора -no-pie — отключает эту защиту и позволяет получить не перемещаемый код.
Последние версии компилятора и линкера GCC по умолчанию генерируют выполняемый код, не зависящий от положения в памяти, или перемещаемый код (position independent executable – PIE).
Это делается для защиты от хакеров, исследующих, как память используется программой, что в итоге позволяет им воздействовать на выполнение программы.
Такая программа слишком сложна для анализа (усложнение делается преднамеренно из соображений обеспечения безопасности).
Ключ компилятора -no-pie — отключает эту защиту и позволяет получить не перемещаемый код.
#32_BASH
Команда ld (GNU линкер в Linux) — используется для компоновки объектных файлов в исполняемые файлы или библиотеки.
Она является частью набора инструментов GNU Binutils и играет ключевую роль в процессе сборки программ на языке C/C++ и других ЯП, поддерживающих создание объектных файлов.
Основная функция команды ld — заключается в том, чтобы связать вместе различные объектные файлы (.o), библиотеки (.a или *.so) и другие компоненты, необходимые для создания конечного исполняемого файла или библиотеки.
Во время этого процесса компоновщик решает ссылки между различными частями программы, такими как функции и переменные, размещает секции данных и кода в памяти и создает итоговую программу.
Основные опции команды ld:
Пример использования.
Предположим, у нас есть два объектных файла main.o и funcs.o, а также библиотека libmath.a. Мы можем создать исполняемый файл следующим образом:
Здесь мы создаем исполняемый файл myprogram, используя объектные файлы main.o и funcs.o, а также подключаем библиотеку libmath.a, находящуюся в каталоге /path/to/libs.
Команда ld — инструмент для управления процессом компиляции и сборки программ в Linux.
Она предоставляет разработчикам гибкость и контроль над тем, как создаются исполняемые файлы и библиотеки, позволяя оптимизировать процесс разработки и настройки программного обеспечения под конкретные нужды.
Команда ld (GNU линкер в Linux) — используется для компоновки объектных файлов в исполняемые файлы или библиотеки.
Она является частью набора инструментов GNU Binutils и играет ключевую роль в процессе сборки программ на языке C/C++ и других ЯП, поддерживающих создание объектных файлов.
Основная функция команды ld — заключается в том, чтобы связать вместе различные объектные файлы (.o), библиотеки (.a или *.so) и другие компоненты, необходимые для создания конечного исполняемого файла или библиотеки.
Во время этого процесса компоновщик решает ссылки между различными частями программы, такими как функции и переменные, размещает секции данных и кода в памяти и создает итоговую программу.
Основные опции команды ld:
-o <output> — определяет имя выходного файла.
Например, -o myprogram;
-L <path> — указывает путь к каталогу, содержащему библиотеки.
Например, -L/usr/local/lib;
-l <library> — подключает библиотеку.
Например, -lm подключит математическую библиотеку libm;
-shared — создает разделяемую библиотеку (.so);
-static — использует статические версии библиотек вместо динамических;
-T <linker_script> — задает файл сценария линковщика, определяющий, как должны быть размещены секции программы в памяти.
Пример использования.
Предположим, у нас есть два объектных файла main.o и funcs.o, а также библиотека libmath.a. Мы можем создать исполняемый файл следующим образом:
$ ld -o myprogram main.o funcs.o -L/path/to/libs -lmath
Здесь мы создаем исполняемый файл myprogram, используя объектные файлы main.o и funcs.o, а также подключаем библиотеку libmath.a, находящуюся в каталоге /path/to/libs.
Команда ld — инструмент для управления процессом компиляции и сборки программ в Linux.
Она предоставляет разработчикам гибкость и контроль над тем, как создаются исполняемые файлы и библиотеки, позволяя оптимизировать процесс разработки и настройки программного обеспечения под конкретные нужды.
#33_ASM
ОСНОВНЫЕ ЧАСТИ ПРОГРАММЫ НА АССЕМБЛЕРЕ (NASM):
section .data
section .bss
section .txt
section .DATA — в разделе section .data объявляются и определяются инициализируемые данные в следующем формате:
<variable name> <type> <value>
Пример:
msg db "Hello, world!",10
msg — имя переменной,
db — тип переменной,
"Hello, world!" — строка сохраняемая в памяти,
10 — ascii код символа новой строки.
Раздел section .data также может содержать константы, т. е. значения, которые невозможно изменить в программе.
Константы определяются в следующем формате:
<constant name> equ <value>
Пример:
pi equ 3.1415926
ОСНОВНЫЕ ЧАСТИ ПРОГРАММЫ НА АССЕМБЛЕРЕ (NASM):
section .data
section .bss
section .txt
section .DATA — в разделе section .data объявляются и определяются инициализируемые данные в следующем формате:
<variable name> <type> <value>
Пример:
msg db "Hello, world!",10
msg — имя переменной,
db — тип переменной,
"Hello, world!" — строка сохраняемая в памяти,
10 — ascii код символа новой строки.
Раздел section .data также может содержать константы, т. е. значения, которые невозможно изменить в программе.
Константы определяются в следующем формате:
<constant name> equ <value>
Пример:
pi equ 3.1415926
#34_ASM
section .BSS
Аббревиатура bss означает Block Started by Symbol (блок, начинающийся с символа) и ведет свое происхождение с 1950-х годов, когда этот блок был компонентом языка ассемблера, разработанного для IBM 704.
В этот раздел помещаются не инициализированные переменные.
Для таких неинициализированных переменных выделяемое пространство памяти объявляется в следующем формате:
<variable name> <type> <number>
Например, следующая инструкция объявляет пространство памяти для массива из 20 двойных слов:
dArray resd 20
section .BSS
Аббревиатура bss означает Block Started by Symbol (блок, начинающийся с символа) и ведет свое происхождение с 1950-х годов, когда этот блок был компонентом языка ассемблера, разработанного для IBM 704.
В этот раздел помещаются не инициализированные переменные.
Для таких неинициализированных переменных выделяемое пространство памяти объявляется в следующем формате:
<variable name> <type> <number>
Например, следующая инструкция объявляет пространство памяти для массива из 20 двойных слов:
dArray resd 20
#35_ASM
section .TXT
Все действия происходят в разделе section .txt.
Этот раздел содержит код программы и начинается со следующих инструкций:
global main
main:
Часть main — называется меткой (label). Если метка расположена в строке, где после нее нет других символов, то после слова main должно быть записано двоеточие, иначе ассемблер выведет предупреждающее сообщение.
А предупреждающие сообщения не следует игнорировать.
Если за меткой следуют другие инструкции (в той же строке), то двоеточие не обязательно, но все же лучше выработать полезную привычку завершать все метки символом двоеточия.
К тому же это повышает удобство чтения исходного кода.
section .TXT
Все действия происходят в разделе section .txt.
Этот раздел содержит код программы и начинается со следующих инструкций:
global main
main:
Часть main — называется меткой (label). Если метка расположена в строке, где после нее нет других символов, то после слова main должно быть записано двоеточие, иначе ассемблер выведет предупреждающее сообщение.
А предупреждающие сообщения не следует игнорировать.
Если за меткой следуют другие инструкции (в той же строке), то двоеточие не обязательно, но все же лучше выработать полезную привычку завершать все метки символом двоеточия.
К тому же это повышает удобство чтения исходного кода.
#36_BASH_TOS
СПИСОК ПЕРЕМЕННЫХ СРЕДЫ в LINUX.
У каждого процесса имеется список переменных среды, являющийся набором переменных среды, который содержится в памяти пользовательского пространства процесса.
Каждый элемент этого списка состоит из имени и связанного с ним значения.
При создании нового процесса с помощью
fork()
он наследует копию среды своего родителя.
Таким образом, среда предоставляет родительскому процессу механизм для обмена информацией с дочерним процессом.
Когда процесс заменяет программу, запуская новую программу с помощью
exec(),
последняя либо наследует среду, используемую старой программой, либо получает новую среду, указанную как часть вызова exec().
Переменные среды создаются в большинстве оболочек командой export (или командой setenv в оболочке C shell):
$ export MYVAR='Hello world'
Программы на языке Cи могут получать доступ к среде, используя внешнюю переменную (char **environ) и различные библиотечные функции, позволяющие процессу извлекать и изменять значения в его среде.
СПИСОК ПЕРЕМЕННЫХ СРЕДЫ в LINUX.
У каждого процесса имеется список переменных среды, являющийся набором переменных среды, который содержится в памяти пользовательского пространства процесса.
Каждый элемент этого списка состоит из имени и связанного с ним значения.
При создании нового процесса с помощью
fork()
он наследует копию среды своего родителя.
Таким образом, среда предоставляет родительскому процессу механизм для обмена информацией с дочерним процессом.
Когда процесс заменяет программу, запуская новую программу с помощью
exec(),
последняя либо наследует среду, используемую старой программой, либо получает новую среду, указанную как часть вызова exec().
Переменные среды создаются в большинстве оболочек командой export (или командой setenv в оболочке C shell):
$ export MYVAR='Hello world'
Программы на языке Cи могут получать доступ к среде, используя внешнюю переменную (char **environ) и различные библиотечные функции, позволяющие процессу извлекать и изменять значения в его среде.
#37_TOS
ОГРАНИЧЕНИЯ РЕСУРСОВ в LINUX.
Каждый процесс потребляет ресурсы, например открытые файлы, память и время центрального процессора. Используя системный вызов
setrlimit();
процесс может установить верхний предел своего потребления различных ресурсов.
Каждый такой предел имеет два связанных с ним значения:
— мягкое ограничение, ограничивающее тот объем ресурса, который процесс может задействовать;
— жесткое ограничение, представляющее собой верхний предел значения, которое может быть отрегулировано мягким ограничением.
Непривилегированный процесс может изменить свое мягкое ограничение для конкретного ресурса на любое значение в диапазоне от нуля и до соответствующего жесткого ограничения, но свое жесткое ограничение он может только понизить.
Ограничения ресурсов оболочки могут быть отрегулированы с использованием команды
$ ulimit
Эти настройки ограничений наследуются дочерними процессами, создаваемыми оболочкой для выполнения команд.
ОГРАНИЧЕНИЯ РЕСУРСОВ в LINUX.
Каждый процесс потребляет ресурсы, например открытые файлы, память и время центрального процессора. Используя системный вызов
setrlimit();
процесс может установить верхний предел своего потребления различных ресурсов.
Каждый такой предел имеет два связанных с ним значения:
— мягкое ограничение, ограничивающее тот объем ресурса, который процесс может задействовать;
— жесткое ограничение, представляющее собой верхний предел значения, которое может быть отрегулировано мягким ограничением.
Непривилегированный процесс может изменить свое мягкое ограничение для конкретного ресурса на любое значение в диапазоне от нуля и до соответствующего жесткого ограничения, но свое жесткое ограничение он может только понизить.
Ограничения ресурсов оболочки могут быть отрегулированы с использованием команды
$ ulimit
Эти настройки ограничений наследуются дочерними процессами, создаваемыми оболочкой для выполнения команд.
#38_TOS
ОТОБРАЖЕНИЕ В ПАМЯТИ в LINUX.
Системный вызов
mmap();
создает в виртуальном адресном пространстве вызывающего процесса новое отображение в памяти.
Отображения делятся на две категории:
файловое отображение — отображает область файла на виртуальную память вызывающего процесса.
После отображения содержимое файла может быть доступно с помощью операций над байтами в соответствующей области памяти. Страницы отображения автоматически загружаются из файла по мере надобности.
анонимное отображение — не имеет соответствующего файла. Вместо этого страницы отображения получают начальное значение 0.
Отображения в памяти служат для различных целей, включая инициализацию текстового сегмента процесса из соответствующего сегмента выполняемого файла, выделения новой (заполненной нулями) памяти, файлового ввода-вывода (ввода-вывода с отображением в памяти), обмена данными между процессами (через общее отображение в памяти).
ОТОБРАЖЕНИЕ В ПАМЯТИ в LINUX.
Системный вызов
mmap();
создает в виртуальном адресном пространстве вызывающего процесса новое отображение в памяти.
Отображения делятся на две категории:
файловое отображение — отображает область файла на виртуальную память вызывающего процесса.
После отображения содержимое файла может быть доступно с помощью операций над байтами в соответствующей области памяти. Страницы отображения автоматически загружаются из файла по мере надобности.
анонимное отображение — не имеет соответствующего файла. Вместо этого страницы отображения получают начальное значение 0.
Отображения в памяти служат для различных целей, включая инициализацию текстового сегмента процесса из соответствующего сегмента выполняемого файла, выделения новой (заполненной нулями) памяти, файлового ввода-вывода (ввода-вывода с отображением в памяти), обмена данными между процессами (через общее отображение в памяти).
#39_TOS
МЕЖПРОЦЕССНОЕ ВЗАИМОДЕЙСТВИЕ в LINUX.
В Linux, как и во всех современных реализациях UNIX, предоставляется обширный набор механизмов для межпроцессного взаимодействия (Interprocess Communication, IPC), включая следующие:
СИГНАЛЫ, которые используются в качестве признака возникновения события;
КОНВЕЙЕРЫ (известные пользователям оболочек в виде оператора |) и FIFO-буферы, которые могут применяться для передачи данных между процессами;
СОКЕТЫ, которые могут использоваться для передачи данных от одного процесса к другому (данные при этом находятся на одном и том же базовом компьютере либо на различных хостах, связанных по сети);
ФАЙЛОВАЯ БЛОКИРОВКА, позволяющая процессу блокировать области файла с целью предотвращения их чтения или обновления содержимого файла другими процессами;
ОЧЕРЕДИ СООБЩЕНИЙ, которые используются для обмена сообщениями (пакетами данных) между процессами;
СЕМАФОРЫ, которые применяются для синхронизации действий процессов;
СОВМЕСТНО ИСПОЛЬЗУЕМАЯ ПАМЯТЬ, позволяющая двум и более процессам совместно использовать часть памяти. Когда один процесс изменяет содержимое совместно используемой области памяти, изменения тут же могут быть видимы всем остальным процессам.
МЕЖПРОЦЕССНОЕ ВЗАИМОДЕЙСТВИЕ в LINUX.
В Linux, как и во всех современных реализациях UNIX, предоставляется обширный набор механизмов для межпроцессного взаимодействия (Interprocess Communication, IPC), включая следующие:
СИГНАЛЫ, которые используются в качестве признака возникновения события;
КОНВЕЙЕРЫ (известные пользователям оболочек в виде оператора |) и FIFO-буферы, которые могут применяться для передачи данных между процессами;
СОКЕТЫ, которые могут использоваться для передачи данных от одного процесса к другому (данные при этом находятся на одном и том же базовом компьютере либо на различных хостах, связанных по сети);
ФАЙЛОВАЯ БЛОКИРОВКА, позволяющая процессу блокировать области файла с целью предотвращения их чтения или обновления содержимого файла другими процессами;
ОЧЕРЕДИ СООБЩЕНИЙ, которые используются для обмена сообщениями (пакетами данных) между процессами;
СЕМАФОРЫ, которые применяются для синхронизации действий процессов;
СОВМЕСТНО ИСПОЛЬЗУЕМАЯ ПАМЯТЬ, позволяющая двум и более процессам совместно использовать часть памяти. Когда один процесс изменяет содержимое совместно используемой области памяти, изменения тут же могут быть видимы всем остальным процессам.
#40_TOS
СИГНАЛЫ зачастую описываются как «программные прерывания».
Поступление сигнала информирует процесс о том, что случилось какое-то событие или возникли исключительные условия.
Каждый тип сигнала идентифицируется с помощью целочисленного значения, определяемого в символьном имени, имеющем форму
SIGxxxx.
Сигналы отправляются процессу ядром, другим процессом (с соответствующими разрешениями) или самим процессом.
Например, ядро может отправить сигнал процессу, когда произойдет что-нибудь из следующего перечня:
— пользователь набрал на клавиатуре команду прерывания (обычно это Ctrl+C);
— завершился один из дочерних процессов данного процесса;
— истекло время таймера (будильника), установленного процессом;
— процесс попытался получить доступ к неверному адресу в памяти.
В оболочке сигнал процессу можно отправить с помощью команды
$ kill.
Внутри программ ту же возможность может предоставить системный вызов
kill( ).
Когда процесс получает сигнал, он, в зависимости от сигнала, выполняет одно из
следующих действий:
— игнорирует сигнал;
— прекращает свою работу по сигналу;
— приостанавливается, чтобы впоследствии возобновить свое выполнение с получением сигнала специального назначения.
СИГНАЛЫ зачастую описываются как «программные прерывания».
Поступление сигнала информирует процесс о том, что случилось какое-то событие или возникли исключительные условия.
Каждый тип сигнала идентифицируется с помощью целочисленного значения, определяемого в символьном имени, имеющем форму
SIGxxxx.
Сигналы отправляются процессу ядром, другим процессом (с соответствующими разрешениями) или самим процессом.
Например, ядро может отправить сигнал процессу, когда произойдет что-нибудь из следующего перечня:
— пользователь набрал на клавиатуре команду прерывания (обычно это Ctrl+C);
— завершился один из дочерних процессов данного процесса;
— истекло время таймера (будильника), установленного процессом;
— процесс попытался получить доступ к неверному адресу в памяти.
В оболочке сигнал процессу можно отправить с помощью команды
$ kill.
Внутри программ ту же возможность может предоставить системный вызов
kill( ).
Когда процесс получает сигнал, он, в зависимости от сигнала, выполняет одно из
следующих действий:
— игнорирует сигнал;
— прекращает свою работу по сигналу;
— приостанавливается, чтобы впоследствии возобновить свое выполнение с получением сигнала специального назначения.
#41_TOS_TP
ПОТОКИ — в современных реализациях UNIX у каждого процесса может быть несколько потоков выполнения.
Потоки можно представить себе в качестве набора процессов, совместно использующих одну и ту же виртуальную память, а также ряд других атрибутов.
Каждый поток выполняет один и тот же программный код и совместно с другими потоками использует одну и ту же область данных и кучу. Но каждый поток имеет свой СОБСТВЕННЫЙ СТЕК, содержащий локальные переменные и информацию о связанности вызовов функций.
Потоки могут осуществлять взаимный обмен данными через совместно используемые глобальные переменные.
API для работы с потоками предоставляет условные переменные и мьютексы, являющиеся примитивами, позволяющими потокам процесса обмениваться данными и синхронизировать свои действия, в частности их использование общих переменных.
Потоки могут также обмениваться друг с другом данными с применением IPC и механизмов синхронизации.
Основным преимуществом использования потоков является упрощение обмена данными (через глобальные переменные) между сотрудничающими потоками. Кроме того, некоторые алгоритмы более естественно преобразуются в многопоточные реализации,
чем в варианты использования нескольких процессов.
Помимо этого, многопоточные приложения могут легко воспользоваться преимуществами параллельной обработки на многопроцессорном оборудовании.
ПОТОКИ — в современных реализациях UNIX у каждого процесса может быть несколько потоков выполнения.
Потоки можно представить себе в качестве набора процессов, совместно использующих одну и ту же виртуальную память, а также ряд других атрибутов.
Каждый поток выполняет один и тот же программный код и совместно с другими потоками использует одну и ту же область данных и кучу. Но каждый поток имеет свой СОБСТВЕННЫЙ СТЕК, содержащий локальные переменные и информацию о связанности вызовов функций.
Потоки могут осуществлять взаимный обмен данными через совместно используемые глобальные переменные.
API для работы с потоками предоставляет условные переменные и мьютексы, являющиеся примитивами, позволяющими потокам процесса обмениваться данными и синхронизировать свои действия, в частности их использование общих переменных.
Потоки могут также обмениваться друг с другом данными с применением IPC и механизмов синхронизации.
Основным преимуществом использования потоков является упрощение обмена данными (через глобальные переменные) между сотрудничающими потоками. Кроме того, некоторые алгоритмы более естественно преобразуются в многопоточные реализации,
чем в варианты использования нескольких процессов.
Помимо этого, многопоточные приложения могут легко воспользоваться преимуществами параллельной обработки на многопроцессорном оборудовании.