DNK_C_C++_Go_Rust
45 subscribers
14 photos
45 links
DNK - дневник кодера С и С++
Download Telegram
Channel created
#1_C_SYSCL_TOS_TP

В настоящее время штудирую книгу Э.Таненбаума "Современные операционные системы", а именно то, что касается работы с процессами и потоками.


Попробуем разобраться как это работает!


POSIX (англ. Portable Operating System Interface — переносимый интерфейс операционных систем) — набор стандартов, описывающих интерфейсы между ОС и прикладной программой (системный API), библиотеку языка C и набор приложений и их интерфейсов.
Стандарт создан для обеспечения совместимости различных UNIX-подобных ОС и переносимости прикладных программ на уровне исходного кода, но может быть использован и для не-Unix систем.
В POSIX имеется пакет Pthreads, в котором определено более 60 различных функций для работы с потоками.

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

Например отрисовка графики и запрос на удаленный сервер, расчет различных параметров одновременно и т.д. и т.п.
Каким же образом мы можем запрограммировать эти действия в разных потоках?
В ЯП С для этого мы должны подключить библиотеку pthread.h т.е. :
#include <pthread.h>


В ЯП С поток — объект типа pthread_t, который определен в заголовочном файле pthread.h.
Для создания потока применяется функция pthread_create( ), которая имеет следующий прототип:
int pthread_create(
pthread_t *thread,
const pthread_attr_t *attr,
void *(*routine) (void *),
void *arg);


Эта функция принимает следующие параметры:
*thread — указатель на объект pthread_t, который инициализируется;
*attr — указатель на набор атрибутов потока в виде объекта pthread_attr_t. Если атрибуты не нужны, можно передать NULL;
*routine — указатель на функцию, которая запускается в потоке. Подобная функция должна принимать в качестве параметра указатель void*, вместо которого можно передать указатель на любой объект. Однако допускается только один аргумент. Соответственно если надо передать несколько значений, то можно оформить их в массив или структуру.

Возвращаемое значение функции — должно представлять указатель void*. Соответственно также можно возвратить указатель на любой объект. Данное возвращаемое значение будет выступать в качестве результата потока. Опять же здесь мы можем возвратить значение NULL, если оно нам не нужно.

*arg — указатель void*, через который передается значение в запускаемую функцию.
Channel photo updated
#2_TOS_TP

АКТИВНОЕ ОЖИДАНИЕ и СПИН-БЛОКИРОВКА.

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

Блокировка, использующая активное ожидание, называется спин-блокировкой.
#3_MTH_TOS_TP

МЬЮТЕКС - это совместно используемая переменная, которая может находиться в одном из двух состояний: заблокированном или незаблокированном.

Для представления мьютекса достаточно всего одного бита, но на практике зачастую используется целое число, при этом 0 означает незаблокированное, а все остальные значениязаблокированное состояние.

Для работы с мьютексами используются две процедуры:
mutex_lock


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


Если на мьютексе заблокировано несколько потоков, то произвольно выбирается один из них, которому разрешается воспользоваться заблокированностью других потоков.
#4_TOS_TP_MTH

СЕМАФОР - целочисленная переменная для подсчета количества активизаций, отложенных на будущее.
#5_C_IF_MTH_TOS

Интересно знать:
Атомарные функции в Linux состоят из встроенного ассемблерного кода, заключенного в функции языка С, и определены в заголовочных файлах.
#6_MTH_TOS_TP

ФЬЮТЕКС, или fast user space mutex быстрый мьютекс в пользовательском пространстве.

Фьютекс относится к свойствам Linux, реализующим основную блокировку (во многом похожую на мьютекс), но избегающим выпадения в режим ядра до возникновения в этом реальной необходимости.
#7_C_MTH_TOS_TP

Для работы с мьютекстами в Pthreads имеются следующие функции:
  pthread_mutex_init — создание мьютекса;
pthread_mutex_destroy — уничтожение существующего мьютекса;
pthread_mutex_lock — овладение блокировкой или блокирование потока;
pthread_mutex_unlock — разблокировние
pthread_mutex_trylock — овладение блокировкой или выход с ошибкой.
#8_C_MTH_TOS_TP

В дополнение к мьютексам пакет Pthreads предлагает второй механизм синхронизацииУСЛОВНЫЕ ПЕРЕМЕННЫЕ — позволяют потокам блокироваться до выполнения конкретных условий.

Условные переменные и мьютексы всегда используются вместе.

Для работы с условными переменными имеются следующие функции:
  pthread_cond_init — создание условной переменной;
pthread_cond_destroy — уничтожение условной переменной;
pthread_cond_wait — блокировка в ожидании сигнала;
pthread_cond_signal — сигнализирование другому потоку и его активизация;
pthread_cond_broadcast — сигнализирование нескольким потомкам и активизация всех этих потоков.


.
#9_MTH_TOS

Для работы с мьютексами и условными переменными в Pthreads определены следующие типы данных:
pthreads_mutex_t — для мьютексов;
pthreads_cond_t — для условных переменных.


.
#10_TOS_TP

МОНИТОР — в ЯП (языках программирования) высокоуровневый механизм взаимодействия и синхронизации процессов, обеспечивающий доступ к разделяемым ресурсам. Подход к синхронизации двух или более компьютерных задач, использующих общий ресурс, обычно аппаратуру или набор переменных.

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

Что интересно, ЯП С и С++ не поддерживают концепцию мониторов на уровне языка, но мониторы имеются в Ада, C#, Concurrent Pascal, Delphi, Java, Squeak Smalltalk и других ЯП.
#11_ASM

Стало интересно познакомиться поближе с ассемблером.

Вот так выглядит Hello, World! на ассемблере:
;hello.asm
section .data
msg db "Hello, world!",10
section .bss
section .text

global main
main:
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, 14
syscall
mov rax, 60
mov rdi, 0
syscall


А это Makefile сборки hello.asm:
hello: hello.o
gcc -no-pie hello.o -o hello

hello.o: hello.asm
nasm -f elf64 -g -F dwarf hello.asm -l hello.lst

clean:
rm -f hello.o hello.lst


.
#12_NTWK

МУЛЬТИПЛЕКСИРОВАНИЕ - передача по одному каналу связи множества сигналов одновременно.

Существует несколько главных способов мультиплексирования:
- по времени;
- по частоте;
- с кодовым разделением;
- по длинам волн (это оптическая разновидность мультиплексирования с частотным разделением каналов).
🤔1
Мультиплексирование с частотным разделением каналовFDM использует преимущества передачи в полосе пропускания. Спектр делится на диапазоны частот, и каждый пользователь получает эксклюзивный доступ к определенной полосе для отправки сигналов.