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

Поток и процессы в операционной системе, процессоре и программировании

Процессы и потоки в операционной систем е ( ОС)

Для программиста же о перационная система является всего лишь программой или задачей, которую выполняет устройство. ОС имеет «глубокий» доступ к аппаратным системам устройства: процессору, материнской плате, видеокарте, аудиокарте, периферийному оборудованию и т. д., поэтому пользователи считают, что она выполняет несколько задач на компьютере. Хотя она контролирует всего лишь процессы.

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

Каждый отдельный процесс потребляет ресурсы устройства. Главная задача любой операционной системы — контроль потребляемых ресурсов компьютера, а также их ограничение и распределени е между всеми процессами, которые на них претендуют. Главными ресурсами компьютера являются:

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

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

Что такое потоки в операционной системе и процессоре

Мы выяснили, что процесс в операционной системе является неким объектом, которому выделяются системные ресурсы, но самостоятельно он не выполняет код программы. У одного процесса мо жет быть несколько потоков, которые будут выполняться одновременно и параллельно. Важно отметить, что несколько потоков одного процесса будут выполнять отдельные части кода одной программы.

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

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

Что такое потоки в процессоре

один с 4 ядрами по 2 потока, то есть всего 8 потоков;

Заключение

Что такое процесс в ОС? Простыми словами, процессом в операционной системе является каждое отдельно запущенное приложение. Процессы в ОС не взаимосвязаны, поэтому могут работать по отдельности.

Что такое поток в программировании? Это возможность разрабатываемой программы работать параллельно в несколько «веток » ( потоков). Потоки в программировании взаимосвязаны. Потоки одной программы не могут работать отдельно друг от друга.

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

Мы будем очень благодарны

если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.

Источник

Потоки и работа с ними

Многопоточность позволяет увеличивать скорость реагирования приложения и, если приложение работает в многопроцессорной или многоядерной системе, его пропускную способность.

Процессы и потоки

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

Цели применения нескольких потоков

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

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

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

Наконец, можно использовать класс System.Threading.Thread, который представляет управляемый поток. Дополнительные сведения см. в разделе Использование потоков и работа с потоками.

Исключения следует обрабатывать в потоках. Необработанные исключения в потоках, как правило, приводят к завершению процесса. Дополнительные сведения см. в статье Исключения в управляемых потоках.

Источник

Потоки — это Goto параллельного программирования

Автор фото: Rainer Zenz

Сперва — немного истории и отсылок с уже состоявшимся обсуждениям.

Goto considered harmful

На Хабре тема использования/изгнания Goto из программ на языках высокого уровня поднималась неоднократно:
habrahabr.ru/post/114211
habrahabr.ru/post/114470
habrahabr.ru/post/114326
Несомненно, существование Goto — источник нескончаемого холивара. Однако современные языки «общего назначения», приблизительно начиная с Java, не включают в свой синтаксис Goto, по крайней мере в его первозданном виде.

Где Goto ещё в ходу

Отмечу одно часто применяемое, но ещё не упомянутое применение операции прыжка по метке, которое лично меня касается достаточно сильно: языки ассемблера и машинные коды. Практически все архитектуры микропроцессоров имеют инструкции условных и безусловных переходов. Более того, я не припомню ассемблера, в котором аппаратно сделан оператор for или while. В результате программисты, работающие на этом уровне абстракции, вынуждены разбираться со всей мешаниной нелокальных переходов. У Дейкстры по этому поводу есть замечание: «. goto должен быть изгнан из всех высокоуровневых языков (т.е. отовсюду, кроме — может быть — простого машинного кода)» [в оригинале: «everything except —perhaps— plain machine code»].

Опущу описание всех известных аргументов против Goto; желающие могут найти их по ссылкам выше. Напишу сразу вывод, как его понимаю я: использование Goto значительно понижает «высокоуровневость» кода, пряча алгоритм в деталях последовательной реализации. Перейдём лучше к потокам.

В чём заключается проблема потоков

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

Что же, если не потоки?

Как же использовать возможности многоядерной аппаратуры, не прибегая к потокам? Конечно же, есть различные языки программирования, изначально спроектированные с расчётом на эффективное написание параллельных программ. Тут и Erlang, и функциональные языки. Если нужна экстремальная масштабируемость решения, следует искать ответ в них и предлагаемых ими механизмах. Но что делать программистам, использующим более традиционные языки, например, Си++, и/или работающих с уже существующим кодом?

OpenMP — хорошо, да не то

Довольно долго ни в С, ни в C++ (в отличие от, например, более «молодой» Java) наличие параллелизма в программах никак не было отражено, т.е. фактически было отдано на откуп «сторонним» библиотекам вроде Pthread. Довольно давно известен OpenMP, вносящий структурированный fork-join параллелизм в эти языки, а также в Fortran. По моему мнению, этот стандарт не приносит решений, связанных указанными выше проблемами потоков. Т.е. OpenMP — всё ещё слишком низкоуровневый механизм. Последняя ревизия стандарта не предложила повышения уровня абстракции, а добавила возможностей (и сложностей) тем, кто хочет с помощью OpenMP пускать коды на гетерогенных системах (подробнее про версию 4.0 писали на Хабре).

Расширения и библиотеки

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

Расширениями языков и библиотеками, в том числе для параллельного программирования, занимаются многие компании, университеты и комбинации оных. У Intel, есть, конечно же, много раз упоминавшиеся на Хабре варианты и первого, и второго: Intel Cilk Plus, Intel Threading Building Blocks. Выражу своё мнение, что Cilk (Plus) более интересен как средство повышения уровня абстракции параллелизма чем TBB. Радует наличие поддержки его в GCC.

Что ещё почитать

Напоследок хочу поделиться одной книгой. Главная её идея для меня заключается в том, что необходимо внесение понимания о существовании структуры у параллельных приложений в процесс их проектирования. Более того, необходимо обучать этому студентов максимально рано, примерно в то же время, когда им объясняют, почему«goto — это плохо».

Michael McCool, Arch Robison, James Reinders. Structured Parallel Programming — 2012 — parallelbook.com.

В книге, в частности, показаны решения одних и тех же задач с использованием нескольких библиотек/языков параллельного программирования: Intel Cilk Plus, OpenMP, Intel TBB, OpenCL и Intel ArBB. Это позволяет сравнить выразительность и эффективность указанных подходов в различных условиях практических задач.

Источник

2.2 Потоки

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

1. Приступая к работе

Что такое поток?

Большая часть из вас уже знает, что такое поток, однако объясним, что это такое, для новичков в данной теме.

Поток — это по сути последовательность инструкций, которые выполняются параллельно с другими потоками. Каждая программа создает по меньшей мере один поток: основной, который запускает функцию main(). Программа, использующая только главный поток, является однопоточной; если добавить один или более потоков, она станет многопоточной.

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

Потоки SFML или std::thread?

В своей последней версии (2011), стандартная библиотека C++ предоставляет набор классов для работы с потоками. Во время написания SFML, стандарт C++11 еще не был написан и не было никакого стандартного способа создания потоков. Когда SFML 2.0 был выпущен, было много компиляторов, которые не поддерживали этот новый стандарт.

Создание потоков с помощью SFML

Хватит разглагольствований, давайте посмотрим на код. Класс, дающий возможность создавать потоки с помощью SFML, называется sf::Thread, и вот как это (создание потока) выглядит в действии:

В этом коде функции main и func выполняются параллельно после вызова thread.launch(). Результатом этого является то, что текст, выводимый обеими функциями, смешивается в консоли.

Точка входа в поток, т.е. функция, которая будет выполняться, когда поток запускается, должна быть передана конструктору sf::Thread. sf::Thread пытается быть гибким и принимать различные точки входа: non-member функции или методы классов, функции с аргументами или без них, функторы и так далее. Приведенный выше пример показывает, как использовать функцию-член, вот несколько других примеров.

Последний пример, который использует функтор, является наиболее мощным, поскольку он может принимать любые типы функторов и поэтому делает класс sf::Thread совместимым со многими типами функций, которые напрямую не поддерживаются. Эта функция особенно интересна с лямбда-выражениями C++11 или std::bind.

Если вы хотите использовать sf::Thread внутри класса, не забудьте, что он не имеет стандартного конструктора. Поэтому, вы должны инициализировать его в конструкторе вашего класса в списке инициализации:

Если вам действительно нужно создать экземпляр sf::Thread после инициализации объекта, вы можете создать его в куче.

Запуск потока

После того, как вы создали экземпляр sf::Thread, вы должны запустить его с помощью запуска функции.

launch вызывает функцию, которую вы передали в конструктор нового потока, и сразу же завершает свою работу, так что вызывающий поток может сразу же продолжить выполнение.

Остановка потоков

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

Функция ожидания также неявно вызывается деструктором sf::Thread, так что поток не может оставаться запущенным (и бесконтрольным) после того, как его экземпляр sf::Thread уничтожается. Помните это, когда вы управляете вашими потоками (смотрите прошлую секцию статьи).

Приостановка потока

В SFML нет функции, которая бы предоставляла способ приостановки потока; единственный способ приостановки потока — сделать это из кода самого потока. Другими словами, вы можете только приостановить текущий поток. Что бы это сделать, вы можете вызвать функцию sf::sleep:

sf::sleep имеет один аргумент — время приостановки. Это время может быть выражено в любой единице, как было показано в статье про обработку времени.

Обратите внимание, что вы можете приостановить любой поток с помощью данной функции, даже главный поток.

sf::sleep является наиболее эффективным способом приостановить поток: на протяжении приостановки потока, он (поток) практически не потребляет ресурсы процессора. Приостановка, основанная на активном ожидании, вроде пустого цикла while, потребляет 100% ресурсов центрального процессора и делает… ничего. Однако имейте в виду, что продолжительность приостановки является просто подсказкой; реальная продолжительность приостановки (больше или меньше указанного вами времени) зависит от ОС. Так что не полагайтесь на эту функцию при очень точном отсчете времени.

Защита разделяемых данных

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

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

Наиболее распространенным (и используемым) примитивом является мьютекс. Мьютекс расшифровывается как «Взаимное исключение». Это гарантия, что только один поток может выполнять код. Посмотрим, как мьютексы работают, на примере ниже:

Этот код использует общий ресурс (std::cout), и, как мы видим, это приводит к нежелательным результатам. Вывод потоков смешался в консоли. Чтобы убедиться в том, что вывод правильно напечатается, вместо того, чтобы быть беспорядочно смешанным, мы защищаем соответствующие области кода мьютексом.

Первый поток, который достигает вызова mutex.lock(), блокирует мьютекс и получает доступ к коду, который печатает текст. Когда другие потоки достигают вызова mutex.lock(), мьютекс уже заблокирован, и другие потоки приостанавливают свое выполнение (это похоже на вызов sf::sleep, спящий поток не потребляет время центрального процессора). Когда первый поток разблокирует мьютекс, второй поток продолжает свое выполнение, блокирует мьютекс и печатает текст. Это приводит к тому, что текст в консоли печатается последовательно и не смешивается.

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

Защита мьютексов

Не волнуйтесь: мьютексы уже потокобезопасны, нет необходимости их защищать. Но они не безопасны в плане исключений. Что происходит, если исключение выбрасывается, когда мьютекс заблокирован? Он никогда не может быть разблокирован и будет оставаться заблокированным вечно. Все потоки, пытающиеся разблокировать заблокированный мьютекс, будут заблокированы навсегда. В некоторых случаях, ваше приложение будет «заморожено».

Чтобы быть уверенным, что мьютекс всегда разблокирован в среде, в которой он (мьютекс) может выбросить исключение, SFML предоставляет RAII класс, позволяющий обернуть мьютекс в класс sf::Lock. Блокировка происходит в конструкторе, разблокировка происходит в деструкторе. Просто и эффективно.

Помните, что sf::Lock может также быть использован в функциях, которые имеют множество возвращаемых значений.

Распространенные заблуждения

Вещь, часто упускаемая из виду: поток не может существовать без соответствующего экземпляра sf::Thread. Следующий код можно часто увидеть на форумах:

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

В чем дело? Экземпляр sf::Thread является локальным для функции startThread(), поэтому немедленно уничтожаются, когда функция возвращает свое значение. Вызывается деструктор sf::Thread, происходит вызов wait(), как утверждалось выше, результатом этого становится блокировка главного потока, который ожидает завершения функции потока, вместо параллельного выполнения с ней.

Так что не забывайте: вы должны управлять экземплярами sf::Thread, чтобы они жили так долго, как требуется функции потока.

Источник

Процессы и потоки in-depth. Обзор различных потоковых моделей

Здравствуйте дорогие читатели. В данной статье мы рассмотрим различные потоковые модели, которые реализованы в современных ОС (preemptive, cooperative threads). Также кратко рассмотрим как потоки и средства синхронизации реализованы в Win32 API и Posix Threads. Хотя на Хабре больше популярны скриптовые языки, однако основы — должны знать все ;)

Потоки, процессы, контексты.

Системный вызов (syscall). Данное понятие, вы будете встречать достаточно часто в данной статье, однако несмотря на всю мощь звучания, его определение достаточно простое :) Системный вызов — это процесс вызова функции ядра, из приложение пользователя. Режим ядра — код, который выполняется в нулевом кольце защиты процессора (ring0) с максимальными привилегиями. Режим пользователя — код, исполняемый в третьем кольце защиты процессора (ring3), обладает пониженными привилегиями. Если код в ring3 будет использовать одну из запрещенных инструкций (к примеру rdmsr/wrmsr, in/out, попытку чтения регистра cr3, cr4 и т.д.), сработает аппаратное исключение и пользовательский процесс, чей код исполнял процессор в большинстве случаях будет прерван. Системный вызов осуществляет переход из режима ядра в режим пользователя с помощью вызова инструкции syscall/sysenter, int2eh в Win2k, int80h в Linux и т.д.

И так, что же такое поток? Поток (thread) — это, сущность операционной системы, процесс выполнения на процессоре набора инструкций, точнее говоря программного кода. Общее назначение потоков — параллельное выполнение на процессоре двух или более различных задач. Как можно догадаться, потоки были первым шагом на пути к многозадачным ОС. Планировщик ОС, руководствуясь приоритетом потока, распределяет кванты времени между разными потоками и ставит потоки на выполнение.

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

Классификация потоков

Классификация потоков по отображению в режим ядра

Модель N:M отображает некоторое число потоков пользовательских процессов N на M потоков режима ядра. Проще говоря имеем некую гибридную систему, когда часть потоков ставится на выполнение в планировщике ОС, а большая их часть в планировщике потоков процесса или библиотеки потоков. Как пример можно привести GNU Portable Threads. Данная модель достаточно трудно реализуема, но обладает большей производительностью, так как можно избежать значительного количества системных вызовов.

Модель N:1. Как вы наверное догадались — множество потоков пользовательского процесса отображаются на один поток ядра ОС. Например волокна.

Классификация потоков по многозадачной модели

Однако, кооперативная многозадачность со временем показала свою несостоятельность. Росли объемы данных хранимых на винчестерах, росла также скорость передачи данных в сетях. Стало понятно, что некоторые потоки должны иметь больший приоритет, как-то потоки обслуживания прерываний устройств, обработки синхронных IO операций и т.д. В это время каждый поток и процесс в системе обзавелся таким свойством, как приоритет. Подробнее о приоритетах потоков и процессов в Win32 API вы можете прочесть в книге Джефри Рихтера, мы на этом останавливатся не будем ;) Таким образом поток с большим приоритетом, может вытеснить поток с меньшим. Такой прицип лег в основу вытесняющей многозадачности (preemptive multitasking). Сейчас все современные ОС используют данный подход, за исключением реализации волокон в пользовательском режиме.

Классификация потоков по уровню реализации

Win32 API Threads

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

Потоки в Win32 создаются с помощью функции CreateThread, куда передается указатель на функцию (назовем ее функцией потока), которая будет выполнятся в созданом потоке. Поток считается завершенным, когда выполнится функция потока. Если же вы хотите гарантировать, что поток завершен, то можно воспользоватся функцией TerminateThread, однако не злоупотребляйте ею! Данная функция «убивает» поток, и отнюдь не всегда делает это корректно. Функция ExitThread будет вызвана неявно, когда завершится функция потока, или же вы можете вызвать данную функцию самостоятельно. Главная ее задача — освободить стек потока и его хендл, т.е. структуры ядра, которые обслуживают данный поток.

Поток в Win32 может пребывать в состоянии сна (suspend). Можно «усыпить поток» с помощью вызова функции SuspendThread, и «разбудить» его с помощью вызова ResumeThread, также поток можно перевести в состояние сна при создании, установив значение параметра СreateSuspended функции CreateThread. Не стоит удивлятся, если вы не увидите подобной функциональности в кроссплатформенных библиотеках, типа boost::threads и QT. Все очень просто, pthreads просто не поддерживают подобную функциональность.

Средства синхронихации в Win32 есть двух типов: реализованные на уровне пользователя, и на уровне ядра. Первые — это критические секции (critical section), к второму набору относят мьютексы (mutex), события (event) и семафоры (semaphore).

Критические секции — легковесный механизм синхронизации, который работает на уровне пользовательского процесса и не использует тяжелых системных вызовов. Он основан на механизме взаимных блокировок или спин локов (spin lock). Поток, который желает обезопасить определенные данные от race conditions вызывает функцию EnterCliticalSection/TryEnterCriticalSection. Если критическая секция свободна — поток занимает ее, если же нет — поток блокируется (т.е. не выполняется и не отъедает процессорное время) до тех пор, пока секция не будет освобождена другим потоком с помощью вызова функции LeaveCriticalSection. Данные функции — атомарные, т.е. вы можете не переживать за целостность ваших данных ;)

Posix Threads или pthreads

Сложно представить, какая из *nix подобных операционных систем, не реализует этот стандарт. Стоит отметить, что pthreads также используется в различных операционных системах реального времени (RTOS), потому требование к этой библиотеке (вернее стандарту) — жестче. К примеру, поток pthread не может пребывать в состоянии сна. Также в pthread нет событий, но есть гораздо более мощный механизм — условных переменных (conditional variables), который с лихвой покрывает все необходимые нужды.

Поговорим об отличиях. К примеру, поток в pthreads может быть отменен (cancel), т.е. просто снят с выполнения посредством системного вызова pthread_cancel в момент ожидания освобождения какого-нибудь мьютекса или условной переменной, в момент выполнения вызова pthread_join (вызывающий поток блокируется до тех пор, пока не закончит свое выполнение поток, приминительно к которому была вызвана функция) и т.д. Для работы с мьютексами и семафорами существует отдельные вызовы, как-то pthread_mutex_lock/pthread_mutex_unlock и т.д.

Conditional variables (cv) обычно используется в паре с мьютексами в более сложных случаях. Если мьютекс просто блокирует поток, до тех пор, пока другой поток не освободит его, то cv создают условия, когда поток может заблокировать сам себя до тех пор, пока не произойдет какое-либо условия разблокировки. Например, механизм cv помогает эмулировать события в среде pthreads. Итак, системный вызов pthread_cond_wait ждет, пока поток не будет уведомлен о том, что случилось определенное событие. pthread_cond_signal уведомляет один поток из очереди, что cv сработала. pthread_cond_broadcast уведомляет все потоки, которые вызывали pthread_cond_wait, что сработала cv.

Прощальное слово

На сегодня пожалуй все, иначе информации станет слишком много. Для интересующихся, есть несколько полезных ссылок и книг внизу ;) Также высказывайте свое мнение, интересны ли вам статьи по данной теме.

UPD: дополнил статью небольшой информацией о режиме ядра и режиме пользователя.
UPD2: исправил досадные промахи и ошибки. Спасибо комментаторам ;)

Источник

Понравилась статья? Поделиться с друзьями:

Не пропустите наши новые статьи:

  • что такое поток в программировании java
  • что такое потенциально нежелательная программа
  • что такое постбэк в партнерской программе
  • что такое постановка задачи в программировании
  • Что такое порядок инсталляции программного обеспечения

  • Операционные системы и программное обеспечение
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest
    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии