Сергей Яковлев
Мой блокнот, мастерская, место где я делюсь своим опытом и мыслями

Описание потока

Эта заметка посвящена потокам. Почитать о процессах и сравнить их с потоками вы можете в предыдущей моей заметке.

Цель этой и последующих заметок — собрать мысли в кучу, в первую очередь для себя. Но я не против поделиться своими изысканиями с общественностью. В конце заметки я укажу ссылки на дополнительные материалы, ознакомившись с которыми, вы сможете получить более исчерпывающую информацию. Кроме того, важно заметить, что все нижесказанное в пераую очередь относится к POSIX-совестимым системам. В Windows всё чуть иначе и я не буду останавливаться на различиях. Если вы заметили неточность или хотели бы, чтобы я добавил что-то интересное, напишите в комментариях или лично мне.

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

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

Модель конкурентного выполнения сопрограмм (сoncurrency) - это немного более широкий термин, чем параллелизм. Данная модель предполагает, что несколько задач могут выполняться одновременно, но не говорит как это должно быть достигнуто. В англоязычном мире есть поговорка, "Concurrency does not imply parallelism".

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

В Linux потоки реализованы с помощью системного вызова clone(), который как минимум в 10 раз меньше занимает времени для создания еще одного потока, чем создание еще одного процесса при помощи fork(). Такая скорость достигается за счет того, что многие атрибуты процесса разделяются между потоками.

Что важно знать о потоках, так это то, что они лучше подходят для задач, связанных с вводом-выводом. В то время как задачи ориентированные процессорные вычисления (CPU-bound), характеризуется постоянной интенсивной работой ядер компьютера от начала до конца, в задачах ориентированных на ввод-вывод (IO-bound) преобладает длительное ожидание завершения ввода-вывода.

Python

Для Python существует встроенный модуль, предоставляющий высокоуровневый интерфейс к реализации параллельного выполнения кода с использованием многопоточности: threading.

Литература

  • Майкл Керриск. «Linux API. Исчерпывающее руководство». Питер, 2019. Глава 6. Потоки выполнения: введение, стр. 627

Комментариев пока нет.