Обзор моделей резьбы Многие люди не понимают, как многопоточность реализована в различных языках программирования.
В наше время многоядерных процессоров такие знания будут очень полезны.
Вот вам небольшой обзор.
Начало (C и собственные потоки)
Первая модель, которую мы рассмотрим, — это стандартные потоки ОС.Каждая современная ОС поддерживает их, несмотря на разницу в API. По сути, поток — это процесс выполнения инструкций, выполняемый на выделенном процессоре, выполнение которого контролируется планировщиком ОС и который может быть заблокирован.
Потоки создаются внутри процесса и совместно используют общие ресурсы.
Это означает, что, например, дескрипторы памяти и файлов используются всеми потоками процесса.
Этот подход обычно называют собственными потоками.
Linux позволяет использовать эти потоки с помощью библиотеки pthread. BSD также поддерживают pthreads. Потоки Windows работают немного по-другому, но основной принцип тот же.
Java и зеленые потоки
Когда вышла Java, она принесла с собой еще один тип многопоточности, называемый зелеными потоками.Зеленые нити по сути являются имитацией нитей.
Виртуальная машина Java заботится о переключении между различными зелеными потоками, а сама машина работает как один поток ОС.
Это дает несколько преимуществ.
Потоки ОС относительно дороги в большинстве систем POSIX. Кроме того, переключение между собственными потоками происходит гораздо медленнее, чем переключение между зелеными потоками.
Это все означает, что в некоторых ситуациях зеленые потоки гораздо выгоднее, чем родные.
Система может поддерживать гораздо большее количество зеленых потоков, чем потоки ОС.
Например, гораздо практичнее запустить новый зеленый поток для нового HTTP-соединения с веб-сервером, а не создавать новый собственный поток.
Однако есть и недостатки.
Самый большой из них заключается в том, что вы не можете запускать два потока одновременно.
Поскольку имеется только один собственный поток, он единственный вызывается планировщиком ОС.
Даже если у вас несколько процессоров и несколько зеленых потоков, только один процессор может вызвать зеленый поток.
А все потому, что с точки зрения планировщика задач ОС все это выглядит как один поток.
Начиная с версии 1.2 Java поддерживает собственные потоки, и с тех пор они используются по умолчанию.
Питон
Python — один из моих любимых языков сценариев, он одним из первых предложил многопоточность.Python включает модуль, который позволяет вам манипулировать собственными потоками, поэтому он может в полной мере использовать преимущества настоящей многопоточности.
Но есть одна проблема.
Python использует глобальную блокировку интерпретатора (GIL).
Эта блокировка необходима, чтобы потоки не могли испортить глобальное состояние интерпретатора.
Следовательно, две инструкции Python не могут выполняться одновременно.
GIL высвобождается примерно каждые 100 инструкций, после чего другой поток может получить блокировку и продолжить свое выполнение.
На первый взгляд это может показаться серьезным недостатком, но на практике проблема не так уж велика.
Любой заблокированный поток обычно освобождает GIL. Расширения C также освобождают его, когда он не взаимодействует с API Python/C, поэтому интенсивные вычисления можно перенести на C и избежать блокировки запуска потоков Python. Единственная ситуация, когда GIL действительно представляет проблему, — это когда поток Python пытается выполниться на многоядерной машине.
Stackless Python — это версия Python, которая добавляет «тасклеты» (на самом деле зеленые потоки).
На их основе был создан модуль greenlet, совместимый со стандартом де-факто: cPython.
Рубин
Модель потоков Ruby постоянно меняется.Изначально Ruby поддерживал только свою версию зеленых потоков.
Это хорошо работает во многих сценариях, но не позволяет воспользоваться возможностями многопроцессорной обработки.
JRuby перевел потоки Ruby в стандартные потоки Java, которые, как мы выяснили выше, являются нативными потоками.
И это создавало проблемы.
Потоки Ruby не нуждаются в синхронизации друг с другом.
Каждому потоку гарантируется, что ни один другой поток не получит доступ к используемому им общему ресурсу.
Такое поведение было нарушено в JRuby, поскольку собственные потоки переключаются упреждающе, и поэтому любой поток может получить доступ к общему ресурсу в любое время.
Из-за этой несогласованности и желания получить собственные потоки разработчики C Ruby решили, что Ruby перейдет на них в версии 2.0. В Ruby 1.9 появился новый интерпретатор, в который добавлена поддержка волокон, которые, по моему мнению, являются более эффективной версией зеленых потоков.
Короче говоря, модель потоков Ruby — это плохо документированная путаница.
Перл
Perl предлагает интересную модель, которую Mozilla позаимствовала у SpiderMonkey, если я не ошибаюсь.Вместо использования глобальной блокировки интерпретатора, как в Python, Perl делает глобальное состояние локальным и фактически запускает новый интерпретатор для каждого нового потока.
Это позволяет вам использовать настоящие собственные потоки.
Не обошлось и без пары загвоздок.
Во-первых, вы должны явно сделать переменные доступными для других потоков.
Вот что происходит, когда все становится локальным потоком.
Нам приходится синхронизировать значения для межпотоковой связи.
Во-вторых, создание нового потока стало очень дорогостоящей операцией.
Интерпретатор — это большая вещь, и его многократное копирование требует много ресурсов.
Erlang, JavaScript, C# и т. д.
Есть много других моделей, которые время от времени находят применение.Например, Erlang использует архитектуру «ничего общего», которая поощряет использование облегченных пользовательских процессов вместо потоков.
Эта архитектура отлично подходит для параллельного программирования, поскольку она устраняет все проблемы с синхронизацией, а процессы настолько легки, что вы можете создавать их столько, сколько захотите.
Обычно JavaScript не считают языком, поддерживающим многопоточность, но он и здесь необходим.
Модель потоков JavaScript очень похожа на модель Perl. C# использует собственные потоки.
От себя: свое раздражение по поводу некоторой поверхностности статьи (о которой я сам осознаю) адресуйте автору.
Я просто перевел в меру своих скромных возможностей.
;) Буду рад уточнениям и дополнениям в комментариях.
От себя 2: на основании комментариев исправил пару фраз.
Извините, автор! :) Теги: #threads #threading #threads #разработка сайтов
-
Дополнительные Примечания: Облако Iaas.
19 Oct, 24 -
О Том, Как Глаза Воспринимают Картинку
19 Oct, 24 -
Создание Вредоносного По. Ответственность
19 Oct, 24