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

Когда я услышал о новом приложении для социальных сетей «Threads» от Meta, первое, что пришло мне в голову, было: не придумал ли его название какой-то программист или системный инженер? Хотя потоковое и многопоточное программирование является важной вычислительной концепцией, многие начинающие программисты, кажется, не знают об этом. В этой статье я коснусь того, что такое потоки, многопоточное программирование и других связанных с ним понятий.

Процессы

Процесс — это экземпляр программы, работающей на компьютере.

Обсуждения

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

Переключение контекста

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

Условие гонки

Ошибка в многопоточном процессе, когда код потока A полагается на поток B для выполнения некоторых действий, но при этом между двумя потоками нет синхронизации. Процесс работает, если поток B выигрывает гонку, завершая свое действие до того, как это потребуется потоку, но процесс терпит неудачу, если поток A выигрывает гонку.

Тупик

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

Объекты синхронизации

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

Примеры объекта/концепции синхронизации:

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

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

Критический раздел — часть кода, которая обращается к общему ресурсу.

Объекты событий — объект ядра, единственная цель которого — быть сигнальным или несигнальным.

Различия между критической секцией и мьютексом:

  1. Для блокировки бесхозного мьютекса требуется почти в 100 раз больше времени, чем для блокировки бесхозного критического раздела, потому что критический раздел может быть выполнен в пользовательском режиме без участия ядра.
  2. Мьютексы могут использоваться между процессами. Критические секции могут использоваться только в рамках одного процесса.
  3. Вы можете указать тайм-аут при ожидании мьютекса, но не критической секции.

Простой пример программирования потоков (C++):

#include <windows.h>
DWORD WINAPI ThreadFunc(LPVOID);

main( )
{
 HANDLE hThread;
DWORD threadId;

hThread = CreateThread(NULL, 0, ThreadFunc, 0, 0, &threadid);
printf(“Thread Running”);
}

DWORD WINAPI ThreadFunc(LPVOID p)
{
 //…………..
}

Очень типичным примером приложения, использующего многопоточное программирование, может быть веб-сервер, такой как веб-сервер Apache или Microsoft IIS. Веб-серверы — это в основном приложения, которые постоянно прослушивают порты 80 (HTTP) и 443 (HTTPS) для запросов. Когда есть новый входящий запрос, веб-сервер должен создать новый рабочий поток для обслуживания запроса, чтобы основной поток мог продолжать прослушивать другие запросы.

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