Posix win threads for windows что это за программа

Современные операционные системы и микропроцессоры уже давно поддерживает многозадачность и вместе с тем, каждая из этих задач может выполняться в несколько

Содержание

  1. Pthreads: Потоки в русле POSIX
  2. Общие сведения
  3. Отображение потоков в режим ядра
  4. Потоки POSIX
  5. Создание потока
  6. Завершение потока
  7. Ожидание потока
  8. Досрочное завершение потока
  9. Отсоединение потока
  10. Потоки versus процессы
  11. Национальная библиотека им. Н. Э. Баумана Bauman National Library
  12. Персональные инструменты
  13. POSIX Threads
  14. Содержание
  15. Причины использования потоков
  16. Основные функции
  17. Мьютексы в пакете Pthreads
  18. Условные переменные
  19. Блокировка чтения-записи
  20. Барьеры
  21. Спинлок
  22. Заключение
  23. Реализации POSIX Threads API
  24. 1. Пользовательские нити
  25. 2. Системные нити
  26. 3. Гибридная реализация
  27. 4. Сборка приложений с POSIX Threads
  28. 5. Программы для экспериментов
  29. темы mingw-w64: posix vs win32
  30. 3 ответов
  31. Глава 12
  32. Что такое поток?
  33. Достоинства и недостатки потоков
  34. Первая программа с применением потоков

Pthreads: Потоки в русле POSIX

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

image loader

В этой статье мы познакомимся с POSIX Threads для того, чтобы затем узнать как это все работает в Linux. Не заходя в дебри синхронизации и сигналов, рассмотрим основные элементы Pthreads. Итак, под капотом потоки.

Общие сведения

image loader

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

В чем польза множественных потоков исполнения? Возьмем какой-нибудь загруженный веб сервер, например habrahabr.ru. Если бы сервер создавал отдельный процесс для обслуживания каждого http запроса, мы бы ожидали вечно пока загрузится наша страница. Создания нового процесса — дорогостоящее удовольствие для ОС. Даже учитывая оптимизацию за счет копирования при записи, системные вызовы fork и exec создают новые копии страниц памяти и списка файловых описателей. В целом ядро ОС может создать новый поток на порядок быстрее, чем новый процесс.

image loader

Таблицы страниц до и после изменения общей страницы памяти во время копирования при записи.

image loader

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

Закон Амдаля для распараллеливания процессов.

image loader

Используя уравнение, показанное на рисунке, можно вычислить максимальное улучшение производительности системы, использующей N процессоров и фактор F, который указывает, какая часть системы не может быть распараллелена. Например 75% кода запускается параллельно, а 25% — последовательно. В таком случае на двухядерном процессоре будет достигнуто 1.6 кратное ускорение программы, на четырехядерном процессоре — 2.28571 кратное, а предельное значение ускорения при N стремящемся к бесконечности равно 4.

Отображение потоков в режим ядра

Практически все современные ОС — включая Windows, Linux, Mac OS X, и Solaris — поддерживают управление потоками в режиме ядра. Однако потоки могут быть созданы не только в режиме ядра, но и в режиме пользователя. При использовании этого уровня ядро не знает о существовании потоков — все управление потоками реализуется приложением с помощью специальных библиотек. Пользовательские потоки по разному отображаются на потоки в режиме ядра. Всего существует три модели, из которых 1:1 является наиболее часто используемой.

Отображение N:1

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

image loader

Отображение 1:1

Это самая проста модель, в которой каждый поток созданный в каком-нибудь процессе непосредственно управляется планировщиком ядра ОС и отображается на один единственный поток в режиме ядра. Чтобы приложение не плодило бесконтрольно потоки, перегружая ОС, вводят ограничение на максимальное количество потоков поддерживаемых в ОС. Данный способ отображения потоков поддерживают ОС Linux и Windows.

image loader

Отображение M:N

При таком подходе M пользовательских потоков мультиплексируются в такое же или меньшее N количество потоков ядра. Преодолеваются негативные эффекты двух других моделей: нити по-настоящему исполняются параллельно и нет необходимости в ОС вводить ограничения на их общее количество. Вместе с тем данную модель довольно трудно реализовать с точки зрения программирования.

image loader

Потоки POSIX

В конце 1980-х и начале 1990-х было несколько разных API, но в 1995 г. POSIX.1c стандартизовал потоки POSIX, позже это стало частью спецификаций SUSv3. В наше время многоядерные процессоры проникли даже в настольные ПК и смартфоны, так что у большинства машин есть низкоуровневая аппаратная поддержка, позволяющая им одновременно выполнять несколько потоков. В былые времена одновременное исполнение потоков на одноядерных ЦПУ было лишь впечатляюще изобретательной, но очень эффективной иллюзией.

Pthreads определяет набор типов и функций на Си.

Из man errno
Переменная errno определена в стандарте ISO C как изменяемое lvalue int и не объявляемая явно; errno может быть и макросом. Переменная errno является локальным значением нити; её изменение в одной нити не влияет на её значение в другой нити.

Создание потока

При удачном завершении pthread_create() возвращает код 0, ненулевое значение сигнализирует об ошибке.

Рассмотрим теперь пример многопоточной программы.

Завершение потока

Поток завершает выполнение задачи когда:

Синтаксис проще, чем при создании потока.

Ожидание потока

При удачном завершении pthread_join() возвращает код 0, ненулевое значение сигнализирует об ошибке.

Досрочное завершение потока

При удачном завершении pthread_cancel() возвращает код 0, ненулевое значение сигнализирует об ошибке.

Небольшая иллюстрация создания и отмены потока.

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

image loader

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

При удачном завершении pthread_detach() возвращает код 0, ненулевое значение сигнализирует об ошибке.

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

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

В начальной части статьи мы уже указывали на эти преимущество, поэтому вкратце их просто перечислим.

Теперь немного о недостатках.

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

Источник

Национальная библиотека им. Н. Э. Баумана
Bauman National Library

Персональные инструменты

POSIX Threads

POSIX Threads

Communications protocol
Purpose позволяет программе контролировать множество разных потоков, накладывающихся во время
Developer(s) POSIX.1c, Threads extensions (IEEE Std 1003.1c-1995)
Introduced 1995 ; 26 years ago ( 1995 )
Based on C
Influenced POSIX 1003.1-2001

Содержание

Причины использования потоков

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

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

Вторым аргументом в пользу потоков является легкость (то есть быстрота) их создания и ликвидации по сравнению с более «тяжеловесными» процессами. Во многих системах создание потоков осуществляется в 10–100 раз быстрее, чем создание процессов. Это свойство особенно пригодится, когда потребуется быстро и динамично изменять количество потоков. [Источник 1]

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

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

Основные функции

В стандарте определено более 60 вызовов функций. Они могут быть разделены на 4 категории:

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

Вызовы, связанные с потоком Описание
pthread_create Создание нового потока
pthread_exit Завершение работы вызвавшего потока
pthread_join Ожидание выхода из указанного потока
pthread_yield Освобождение центрального процессора, позволяющее

выполняться другому потоку

pthread_attr_init Создание и инициализация структуры атрибутов потока
pthread_attr_destroy Удаление структуры атрибутов потока

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

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

Чтобы лучше понять, как работают функции пакета Pthread, рассмотрим простой пример, показанный ниже. Основная программа этого примера работает в цикле столько раз, cколько указано в константе NUMBER_OF_THREADS (количество потоков), создавая при каждой итерации новый поток и предварительно сообщив о своих намерениях. Если создать поток не удастся, она выводит сообщение об ошибке и выполняет выход. После создания всех потоков осуществляется выход из основной программы. При создании поток выводит однострочное сообщение, объявляя о своем существовании, после чего осуществляет выход. Порядок, в котором выводятся различные сообщения, не определен и при нескольких запусках программы может быть разным.

Мьютексы в пакете Pthreads

pthread_mutex_init Создание мьютекса
pthread_mutex_destroy Уничтожение существующего мьютекса
pthread_mutex_lock Овладение блокировкой или блокирование потока
pthread_mutex_trylock Овладение блокировкой или выход с ошибкой
pthread_mutex_unlock Разблокирование

Условные переменные

Наиболее важные вызовы, связанные с условными переменными, показаны в таблице. В ней представлены вызовы, предназначенные для создания и уничтожения условных переменных.

Вызов из потока Описание
pthread_cond_init Создание условной переменной
pthread_cond_destroy Уничтожение условной переменной
pthread_cond_wait Блокировка в ожидании сигнала
pthread_cond_signal Сигнализирование другому потоку и его активизация
pthread_cond_broadcast Сигнализирование нескольким потокам и активизация всех этих потоков

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

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

Блокировка чтения-записи

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

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

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

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

Барьеры

Где последний параметр count задает число нитей, которые должны дойти до барьера (вызвать функцию pthread_barrier_wait ) прежде чем они смогут продолжить выполнение. Раз существует функция инициализирующая барьер, то существует и комплиментарная функция которая уничтожает его:

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

Спинлок

Третий примитив синхронизации, про который хотелось бы поговорить это spin lock(спинлок). С точки зрения функциональности этот примитив ничем не отличается от мьютекса. Основная стоящая за ними идея состоит в том, чтобы вместо того чтобы заблокировать нить в случае если блокировка уже захвачена, крутиться, проверяя не освободилась ли блокировка (отсюда и слово spin в названии). Фактически спинлок это мьютекс основанный на использовании активного ожидания. Какой тогда смысл в таком примитиве? В случае если мы имеем мультипроцессор (так как на однопроцессорной машине спинлок будет бесполезно съедать циклы процессора до тех пор, пока не произойдет переключение на другую владеющую блокировкой нить) и крайне малый размер критической секции защищаемой этим примитивом (чтобы опять же не ждать долго и снизить опасность переключения на другую нить) спинлок может быть использован эффективнее чем мьютекс. Это обусловлено тем что он не вызывает долгой операции перевода нити в сон, вообще считается что spin lock реализуется на основе самых быстрых механизмов синхронизации доступных в системе. В случае если какое-либо из двух вышеприведенных условий нарушается, спинлок не даст выигрыша в производительности и выгоднее воспользоваться мьютексом. Согласно стандарту данный примитив представляется при помощи типа pthread_spinlock_t и набора операций над ним, которые практически совпадают с соответствующими операциями для мьютекса:

Заключение

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

Источник

Реализации POSIX Threads API

Так и живем, не пропустив ни дня,

И каждый день проходит словно дважды.

Стандарт POSIX допускает различные подходы к реализации многопоточности в рамках одного процесса. Возможны три основных подхода:

Как правило, при этом количество пользовательских нитей в процессе может превосходить количество системных нитей.

1. Пользовательские нити

Реализация планировщика в пользовательском адресном пространстве не представляет больших сложностей; наброски реализаций таких планировщиков приводятся во многих учебниках по операционным системам, в том числе в [Иртегов 2002]. Учебная многозадачная ОС Minix может быть собрана и запущена в виде задачи под обычной Unix-системой; при этом процессы Minix будут с точки зрения ядра системы-хозяина пользовательскими нитями. Главным достоинством пользовательского планировщика считается тот факт, что он может быть реализован без изменений ядра системы.

2. Системные нити

3. Гибридная реализация

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

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

4. Сборка приложений с POSIX Threads

Ниже приводится пример кода, который позволяет протестировать ваш компилятор и проверить наличие типичных препроцессорных символов, используемых в include-файлах стандартной библиотеки языка С для проверки того, однопоточная или многопоточная программа сейчас компилируется. _LIBC_REENTRANT используется в Linux, _REENTRANT в Solaris. На других платформах могут использоваться другие символы. Попробуйте собрать эту программу с разными ключами компилятора и проверить результат. Полезно также поискать соответствующие символы в файлах каталога /usr/include и посмотреть, какие именно конструкции они контролируют.

5. Программы для экспериментов

Источник

темы mingw-w64: posix vs win32

Я устанавливаю mingw-w64 на Windows, и есть два варианта: win32 threads и posix threads. Я знаю, в чем разница между потоками win32 и pthreads, но я не понимаю, в чем разница между этими двумя вариантами. Я сомневаюсь, что если я выберу потоки posix, это помешает мне вызывать функции WinAPI, такие как CreateThread.

кажется, что эта опция указывает, какой API потоков будет использоваться некоторой программой или библиотекой, но чем? По НКУ, libstdc++ или что-то еще?

Я нашел это: в чем разница между thread_posixs и thread_win32 в порту gcc windows?

короче говоря, для этой версии mingw выпуск threads-posix будет использовать API posix и разрешать использование std::thread, а threads-win32 будет использовать API win32 и отключит часть std::thread стандарта.

Ok, если я выберу win32 threads, то std:: thread будет недоступно, но потоки win32 по-прежнему будут использоваться. Но используется кем?

3 ответов

Я должен подчеркнуть, что эта опция не запрещает вам писать любой код, который вы хотите (он имеет абсолютно нет влияние на то, какой API вы можете вызвать в своем коде). Он отражает только то, что библиотеки времени выполнения GCC (libgcc / libstdc++/. ) использовать для их функциональности. Оговорка, цитируемая @James, не имеет ничего общего с внутренней моделью потоковой передачи GCC, а скорее с реализацией CRT Microsoft.

ни имеют влияние на любой пользовательский код, вызывающий Win32 APIs или Pthreads APIs. Вы всегда можете использовать оба.

части среды выполнения GCC (в частности, обработка исключений) зависят от используемой модели потоков. Таким образом, если вы используете версию среды выполнения, которая была построена с потоками POSIX, но решили создать потоки в своем собственном коде с API Win32, в какой-то момент у вас могут возникнуть проблемы.

даже если вы используете потоковую версию Win32 среды выполнения, вы, вероятно, не должны вызывать API Win32 напрямую. Цитата из компилятор MinGW FAQ:

обратите внимание, что теперь можно использовать некоторые из C++11 std::thread в режиме Win32 threading. Эти адаптеры только для заголовков работали из коробки для меня: https://github.com/meganz/mingw-std-threads

из истории ревизий похоже, что есть какая-то недавняя попытка сделать это частью среды выполнения mingw64.

Источник

Глава 12

В главе 11 вы видели, как обрабатываются процессы в ОС Linux (и конечно в UNIX). Эти средства обработки множественных процессов долгое время были характерной чертой UNIX-подобных операционных систем. Порой бывает полезно заставить одну программу делать два дела одновременно или, по крайней мере, создать впечатление такой работы. А может быть, вы хотите, чтобы несколько событий произошло одновременно и все они были тесно связаны, но при этом накладные расходы на создание нового процесса с помощью функции

В этой главе мы рассмотрим следующие темы:

□ создание новых потоков в процессе;

□ синхронизацию доступа к данным потоков одного процесса;

□ изменение атрибутов потока;

□ управление в одном и том же процессе одним потоком из другого.

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

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

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

Идея потоков была популярна какое-то время, но пока Комитет IEEE POSIX не опубликовал некоторые стандарты, потоки не были широко распространены в UNIX-подобных операционных системах и существовавшие реализации разных поставщиков сильно отличались друг от друга. С появлением стандарта POSIX 1003.1c все изменилось; потоки теперь не только лучше стандартизованы, но также реализованы в большинстве дистрибутивов Linux. В наше время многоядерные процессоры стали обычными даже в настольных компьютерах, так что у большинства машин есть низкоуровневая аппаратная поддержка, позволяющая им выполнять несколько потоков одновременно. Раньше при наличии одноядерных ЦПУ одновременное исполнение потоков было лишь изобретательной, хотя и очень эффективной иллюзией.

Впервые ОС Linux обзавелась поддержкой потоков около 1996 г. благодаря появлению библиотеки, которую часто называют «LinuxThreads» (потоки Linux). Она почти соответствует стандарту POSIX (на самом деле в большинстве случаев отличия не заметны) и стала важным шагом на пути первого применения потоков программистами Linux. Но между реализацией потоков в Linux и стандартом POSIX есть слабые расхождения, в основном касающиеся обработки сигналов. Ограничения накладываются не столько реализацией библиотеки, сколько низкоуровневой поддержкой ядра Linux.

Разные проекты рассматривали возможности улучшения поддержки потоков в Linux, касающиеся не только устранения слабых расхождений со стандартом POSIX, но и повышения производительности и удаления любых ненужных ограничений. Основная работа была направлена на поиск способов отображения потоков пользовательского уровня на потоки уровня ядра системы. Двумя главными проектами были New Generation POSIX Threads (NGPT, потоки POSIX нового поколения) и Native POSIX Thread Library (NPTL, библиотека истинных потоков POSIX). Оба проекта должны были внести изменения в ядро Linux, обеспечивающие поддержку новых библиотек, и оба предлагали существенное повышение производительности по сравнению с прежней реализацией потоков в Linux.

В 2002 г. команда NGPT объявила, что не хочет разделять сообщество и приостанавливает разработку новых средств для проекта NGPT, но продолжит работу по улучшению поддержки потоков в ОС Linux, присоединив свои усилия к стараниям NPTL. Библиотека NPTL стала новым стандартом для потоков в Linux, выпустив первую основную версию в дистрибутиве Red Hat Linux 9. Вы можете найти интересную основополагающую информацию о NPTL в статье «The Native POSIX Thread Library for Linux» («Библиотека истинных потоков POSIX для Linux») Ульриха Дреппера (Ulrich Drepper) и Инго Мольнара (Ingo Molnar), которая во время написания книги была доступна в Интернете по адресу http://people.redhat.com/drepper/nptl-design.pdf.

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

Достоинства и недостатки потоков

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

Далее перечислены некоторые достоинства потоков.

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

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

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

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

У потоков есть и недостатки.

□ Создание многопоточной программы требует очень тщательной разработки. Вероятность появления незначительных временных сбоев или ошибок, вызванных нечаянным совместным использованием переменных, в такой программе весьма значительна. Алан Кокс (Alan Сох, всеми уважаемый гуру Linux) сказал, что потоки равнозначны умению «выстрелить в обе собственные ноги одновременно».

□ Отладка многопоточной программы гораздо труднее, чем отладка одного потока исполнения, поскольку взаимосвязи потоков очень трудно контролировать.

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

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

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

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

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

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

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

□ Некоторые функции из файла stdio.h, которые обычно реализованы как макросы, становятся соответствующими реентерабельными безопасными функциями.

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

int pthread_create(pthread_t * thread, pthread_attr_t *attr,

Прототип выглядит внушительно, но функцию очень легко применять. Первый аргумент — указатель на переменную типа

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

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

Когда поток завершается, он вызывает функцию

Источник

Значок OnWorks


Бесплатно загрузите приложение POSIX Threads для Windows для Windows, чтобы запускать онлайн Win в Ubuntu онлайн, Fedora онлайн или Debian онлайн

Это приложение для Windows под названием POSIX Threads для Windows, последний выпуск которого можно загрузить как pthreads4w-code-v3.0.0.zip. Его можно запустить онлайн в бесплатном хостинг-провайдере OnWorks для рабочих станций.

Загрузите и запустите онлайн это приложение под названием POSIX Threads для Windows бесплатно с OnWorks.

Следуйте этим инструкциям, чтобы запустить это приложение:

— 1. Загрузил это приложение на свой компьютер.

— 2. Введите в нашем файловом менеджере https://www.onworks.net/myfiles.php?username=XXXXX с желаемым именем пользователя.

— 3. Загрузите это приложение в такой файловый менеджер.

— 4. Запустите любой онлайн-эмулятор OS OnWorks с этого сайта, но лучше онлайн-эмулятор Windows.

— 5. В только что запущенной ОС Windows OnWorks перейдите в наш файловый менеджер https://www.onworks.net/myfiles.php?username=XXXXX с желаемым именем пользователя.

— 6. Скачайте приложение и установите его.

— 7. Загрузите Wine из репозиториев программного обеспечения вашего дистрибутива Linux. После установки вы можете дважды щелкнуть приложение, чтобы запустить его с помощью Wine. Вы также можете попробовать PlayOnLinux, необычный интерфейс поверх Wine, который поможет вам установить популярные программы и игры для Windows.

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

Потоки POSIX для Windows

ОПИСАНИЕ

POSIX Threads для Windows, также известный как pthreads-win32, реализует большое подмножество связанных с потоками API из единой спецификации Unix версии 3.

Соответствие и качество — главные приоритеты этой зрелой библиотеки. Разработка началась в 1998 году и продолжилась благодаря многочисленным значительным профессиональным вкладам.

Обратите внимание: — хотя PThreads4W может быть собран и запущен им, MinGW64 включает собственную библиотеку потоков POSIX по умолчанию, которая называется «winpthreads». Они несовместимы, и для сборки и запуска PThreads4W (ранее PThreads-WIn32) MinGW64 должен быть установлен без win32pthreads. Если вы хотите или вам необходимо собрать и запустить с PThreads4W, тогда вам нужно выбрать потоки win32 вместо POSIX при установке MinGW64, чтобы не устанавливать конфликтующие файлы winpthreads include и библиотеки.

Особенности

  • Совместимость с API-интерфейсом Single Unix Specification 3 (POSIX)
  • Поддерживается 64- и 32-битная Windows
  • Поддерживается MSVS или GNU GCC (например, MinGW или MinGW64)
  • Собственные потоки Windows, способные взаимодействовать (синхронизировать и т. Д.) С потоками POSIX через API POSIX.
  • Разработанный для нулевой модификации исходного кода, совместимого с POSIX, он не является эмуляцией, а объекты синхронизации не являются простыми оболочками для эквивалентов Windows.

Аудитория

Застройщики

Язык программирования

C

Это приложение также можно загрузить с https://sourceforge.net/projects/pthreads4w/. Он размещен в OnWorks, чтобы его можно было легко запускать в Интернете с помощью одной из наших бесплатных операционных систем.

Скачать приложения для Windows и Linux

>>

  • Приложения для Linux
  • Приложения для Windows
  • 1

    itop — ITSM CMDB с открытым исходным кодом
    itop — ITSM CMDB с открытым исходным кодом
    Портал ИТ-операций: полностью открытый
    источник, ITIL, веб-сервис
    инструмент управления, включающий полностью
    настраиваемая CMDB, система службы поддержки и
    документальный человек…
    Скачать itop — ITSM CMDB OpenSource
  • 2

    Клементин
    Клементин
    Clementine — это мультиплатформенная музыка.
    проигрыватель и организатор библиотеки, вдохновленный
    Амарок 1.4. Обладает быстрым и
    удобный интерфейс и позволяет
    поиск и…
    Скачать Клементину
  • 3

    XISmuS
    XISmuS
    ВНИМАНИЕ: В накопительном обновлении 2.4.3 есть
    был выпущен !! Обновление работает для любых
    предыдущая версия 2.xx. Если обновление
    начиная с версии v1.xx, скачайте и
    Я …
    Скачать XISmuS
  • 4

    фейстрекнуар
    фейстрекнуар
    Модульная программа отслеживания головы, которая
    поддерживает несколько фейс-трекеров, фильтры
    и игровые протоколы. Среди следопытов
    являются SM FaceAPI, инерционная головка AIC
    Трекер …
    Скачать фейстрекнуар
  • 5

    Ткать
    Ткать
    Коротко о Weaviate: Weaviate — это
    вектор поисковая система и вектор
    база данных. Weaviate использует машинное обучение
    для векторизации и хранения данных, а также для поиска
    ответы…
    Скачать Weaviate
  • 6

    QR-код PHP
    QR-код PHP
    PHP QR-код с открытым исходным кодом (LGPL)
    библиотека для генерации QR-кода,
    2-х мерный штрих-код. На основе
    Библиотека libqrencode C, предоставляет API для
    создание штрих-кода QR-кода …
    Загрузите QR-код PHP
  • 7

    Песочница с кукушкой
    Песочница с кукушкой
    Cuckoo Sandbox использует компоненты для
    контролировать поведение вредоносного ПО в
    Среда песочницы; изолированы от
    остальная часть системы. Он предлагает автоматизированный
    анализ о…
    Скачать Песочницу с кукушкой
  • Больше »

Команды Linux

  • 1

    аа3д
    аа3д
    aa3d — художественная стереограмма в формате ASCII.
    генератор …
    Запустить aa3d
  • 2

    aac-enc
    aac-enc
    aac-enc — создавать аудиофайлы в формате AAC…
    Запустить aac-enc
  • 3

    конвертироватьTextPickle
    конвертироватьTextPickle
    convertTextPickle — Конвертировать Моцарта
    огурцы с версии 1.0.1…
    Запустите convertTextPickle
  • 4

    convertToAtac
    convertToAtac
    sim4dbutils — утилиты для работы
    файлы выравнивания, созданные sim4db
    convertPolishes — конвертировать между sim4db
    и форматы GFF3 filterПолиши — фильтр
    выровнять…
    Запустите convertToAtac
  • 5

    gba3
    gba3
    gba3 — Архиватор GAMBAS…
    Запустить gba3
  • 6

    gфон
    gфон
    gbackground — интервальный гном
    смена фона СИНТАКСИС: gbackground
    ОПИСАНИЕ: Эта программа позволяет
    периодически менять фон гнома
    в меж…
    Запустить gbackground
  • Больше »

Leader badge

Also known as «pthreads-win32», POSIX Threads for Windows implements a large subset of the threads related API from the Single Unix Specification Version 3.

Conformance and quality are high priorities of this mature library. Development began in 1998 and has continued with numerous significant professional contributions.

Please note:- whilst PThreads4W can be built and run by it, MinGW64 includes it’s own default POSIX Threads library called «winpthreads». The two are not compatible and in order to build and run PThreads4W (formerly PThreads-WIn32) MinGW64 must be installed without win32pthreads. If you want or need to build and run with PThreads4W then you need to choose win32 threading instead of POSIX when you install MinGW64 to not install the conflicting winpthreads include and library files.

Features

  • Single Unix Specification 3 (POSIX) Threads API compliant
  • 64 and 32 bit Windows supported
  • MSVS or GNU GCC (e.g. MinGW or MinGW64) supported
  • Windows native threads able to interact (synchronise etc.) with POSIX threads through the POSIX API
  • Designed for zero modification of POSIX compliant source code, it is not an emulation and the synchonisation objects are not simple wrappers for Windows equivalents.

License

GNU Library or Lesser General Public License version 2.0 (LGPLv2)

Connect any person or service to anything in your infrastructure. Icon

We combine authentication, authorization, connectivity, and observability to create frictionless access management across your company’s entire stack, in a way that admins love. That means secure, that means fast, that means convenient and as flexible and automatable as you need it to be.

User Ratings


5.0

out of 5 stars

★★★★★

★★★★

★★★

★★

ease
1 of 5
2 of 5
3 of 5
4 of 5
5 of 5

5 / 5

features
1 of 5
2 of 5
3 of 5
4 of 5
5 of 5

4 / 5

design
1 of 5
2 of 5
3 of 5
4 of 5
5 of 5

0 / 5

support
1 of 5
2 of 5
3 of 5
4 of 5
5 of 5

0 / 5

Additional Project Details

Intended Audience

Developers

Programming Language

C

2012-01-15

В чем разница между thread_posixs и thread_win32 в gcc-порту Windows?

Я хотел загрузить последнюю доступную версию компилятора gcc 4.7.2 для Windows. Когда я попал на эту страницу там, где я должен был увидеть ссылку для скачивания, я столкнулся с двумя категориями:

  1. нитки-posix
  2. темы-win32

В чем разница между этими двумя? Это только реализации потоков? Я имею в виду, отличаются ли они только тем, как они реализованы, и поэтому конечный результат (классы, как их использовать и т. Д.) Остается прежним? Или они навязывают определенный стиль кодирования?

1 ответ

Итак, предоставленная вами ссылка ведет к сборкам автономного gcc 4.7.2 для Windows, также известного как mingw64. Для сборки этого компилятора используется набор скриптов, которые помогают определять параметры компиляций. Скрипты называются просто MinGW-сборками, и их можно найти в разных местах:

В скриптах есть опция, которая указывает, какая модель потока должна использоваться для части std :: threads стандарта C ++ 11 (это разрешено для MinGW благодаря экспериментальный патч, примененный к этой версии GCC). В одном случае используется API потока win32, а в другом — API posix.

Обратите внимание, что Windows не поддерживает все POSIX API из коробки, поэтому необходимо использовать некоторую внешнюю библиотеку эмуляции (winpthreads).

В исходном сценарии конфигурации GCC есть возможность указать этот API (—enable-threads =), и это то, что используется в сценариях сборки.

Короче говоря, для этой версии mingw выпуск thread-posix будет использовать posix API и разрешить использование std :: thread , а thread-win32 будет использовать win32 API, а отключите стандартную часть std :: thread .

Профиль
Группа: Участник
Сообщений: 44
Регистрация: 6.2.2009

Репутация: нет
Всего: нет

И так в бою за титул чемпиона участвует два соперника
Win32Api(будем его так кликать):
OS: Windows NT/95/98/me/2000/xp/vista/seven/ce(может не в той последовательности)

POSIX:
OS: Unix/Linux(many)/Mac OS/QNX/(слышал про реализацию под Windows NT/95/98/me/2000/xp/vista/seven/ce правда уже не в комплекте).

Let’s Begin(Давайте начнем)

1)Round «Mutual blocking(взаимо блокировка)»:

Win32Api представляет CRITICAL_SECTION и и Mutex.
POSIX уверенно говорит о Mutex.

Win32Api:
CRITICAL_SECTION
InitializeCriticalSection();
EnterCriticalSection();
TryEnterCritticalSection();
LeaveCriticalSection();
DeleteCriticalSection();

Просты в использовании, выходят в режим ядра когда это действительно нужно. Из минусов можно сказать большой расход памяти(из-за структуры).
Требуют обработку исключений(по крайней мере InitializeCriticalSection,
а если я использую С, __try __catch __finally вообщем расклад то не очень)
-Распростроняются только на один процесс(хотя при желании можно и изменить, мы ведь знаем что в структуре есть handle семафора, но
наверное не стоит)
Mutex:
CreateMutex();
OpenMutex();
WaitForSingleObject();
WaitForMultiObjects();
ReleaseMutex();
CloseHandle();

Всегда используют ядро. Указатель на void наверное не самое лучшое решение, вдруг захочится узнать кто же все таки блокировал поток?
Но есть и приимущества указатель на void стандартная функция уничножения, и ожидания. Большим приимушеством будет что поток может ожидать
несколько mutex’s. Нет try lock . Так же плюс что является мульти процессорным.

Mutex:
pthread_mutex_init();
pthread_mutex_lock();
pthread_mutex_trylock();
pthread_mutex_unlock();
pthread_mutex_destroy();

Открытая структура, выходят в режим ядра когда это действительно нужно. Распростроняются только на один процесс. Нет возможности ожидания
больше одного mutexю
Кто победил? Трудновато сказать. Тут все завист от то кто что ожидает при использовании «Mutual blocking(взаимо блокировка)». Лично мое мнение это Win32Api.

так что счет 1:0

2)Round «Semaphore»:
Win32Api:
CreateSemaphore();
WaitForSingleObject();
WaitForMultiObjects();
ReleaseSemaphore();
CloseHandle();

В принципе все приимущества что и у Mutex. Не стоит думать как был создан(или же был открыт) семафор при уничтожении. Пожалуй не удобно при открытии
делать дубликацию HANDL.
Posix:
sem_init();
sem_wait();
sem_post();
sem_trywait();
sem_getvalue();
sem_destory();
sem_open();
sem_close();
sem_unlink();
Надо помнить как все же был создан(или был открыт) семафор при уничтожении. Приимучество можно получить счетчик, и есть try wait.

Думаю здесь честно победу можно отдать Win32Api.
Так что счет 2:0

3)Round «Atomic operation or Interlocked(Атомарные операции или Interlocked(мне не нравится перевод))»

Win32Api:
InterlockedDecrement();
InterlockedIncrement();
InterlockedAdd();
Ну и в таком духе.
Приимуществ нет. Не достаток вызывают DLL, соответственно заинлайнится не смогут(может есть какаета другая реализация?).

Posix(не слышал так что воспользуемся linux):
atomic_add();
atomic_sub();
atomic_inc();
atomic_dec();

Инлайнятся.
Говорить о assembler думаю не стоит, но если говорить то легче реализовывать под винду.
Раунд за Linux;
Так что счет 2:1.

4)Round «Thread local storage»

Win32Api:
TlsAlloc();
TlsSetValue();
TlsGetValue();
TlsFree();
Без коментариев.
Posix:
pthread_create_key();
pthread_setspecific();
pthread_getspecific();
pthread_delete_key();
Без коментариев.

В это раунде нечья.

Так что счет 3:2.

Win32Api:
InitializeConditionVariable();
SleepConditionVariableCS();
SleepConditionVariableSRW() — support only vista server 2008 не рассмотриваем.
WakeAllConditionVariable();
WakeConditionVariable();

Я бы сказал не чего особого. Только вот не понятно как уничтожать.
Posix:
pthread_cond_init()
pthread_cond_wait();
pthread_cond_timedwait();
pthread_cond_signal();
pthread_cond_broadcast();
pthread_cond_destroy();

Функция с ожиданием по времени.
Так что Posix +1;

Так что счет 3:3.

Win32Api не имеет барьеров. Создание управление потоками не лучше чем у POSIX, CreateThread/_beginthread/_beginthreadEx по мне менее удобны чем pthread_create,
Хотя бы по тому что параметров не надо столько передавать. Здесь я не писал о spin блокировках, read_write lock, в Win32Api это только в
vista/server2008. Стоит отметить OpenMP но это принадлежит visual studio.

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

Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 6
Всего: 44

Цитата(0xDX @ 6.3.2009, 04:13)
Стоит отметить OpenMP но это принадлежит visual studio.

ЗЫ для чего вообще это сравнение? что оно дало?

Это сообщение отредактировал(а) chaos — 6.3.2009, 07:34

Профиль
Группа: Комодератор
Сообщений: 7045
Регистрация: 28.8.2007
Где: Химки, Московская обл

Репутация: 60
Всего: 223

Уточнение — серия trylock для Win32 API есть — это WaitForSingleObject с 0 в качестве параметра timeout
По поводу void* в качестве handle для Win32API — это ГОРАЗДО лучше, чем открытая структура у пользователя. Система должна сама заботится о защите своих объектов от несанкционированного вмешательства пользователя (да и от санкционированного тоже)
Далее, все серия Interlocked* в Win32API инлайнится компилятором, никаких dll не нужно (конечно, если программист не приложит больших усилий, что бы этого не было )
В posix нет аналога Win32 Event’ов (очень убогий аналог — Conditional Variable)
В posix нет возможности ждать сразу на нескольких разных синхронизирующих примитивах.
По поводу TLS и там и там можно разложить переменные по TLS на этапе компиляции, и не пользоваться tls API совсем

Так что счет будет явно не в пользу posix.

Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 6
Всего: 44

xvr, но хоть это не очень хорошо, но всеже все это можно реализовать» используя то что есть.

» — уже реализовано, например монжо поглядеть в ACE.
ACE_Event & ACE_AutoEvent
на счет ждать нескольких событий, если я не ошибасюь то ACE_Reactor решит проблему. Наверника что-то есть уже готовое в boost::thread — но точно не знаю, не пользуюсь

Это сообщение отредактировал(а) chaos — 6.3.2009, 14:57

Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154

Цитата(0xDX @ 6.3.2009, 07:13 )
Хотя бы по тому что параметров не надо столько передавать. Здесь я не писал о spin блокировках, read_write lock, в Win32Api это только в
vista/server2008.

Профиль
Группа: Комодератор
Сообщений: 7045
Регистрация: 28.8.2007
Где: Химки, Московская обл

Репутация: 60
Всего: 223

Цитата(chaos @ 6.3.2009, 14:54)
xvr, но хоть это не очень хорошо, но всеже все это можно реализовать» используя то что есть.
Цитата
на счет ждать нескольких событий, если я не ошибасюь то ACE_Reactor решит проблему. Наверника что-то есть уже готовое в boost::thread — но точно не знаю, не пользуюсь

Профиль
Группа: Участник
Сообщений: 44
Регистрация: 6.2.2009

Репутация: нет
Всего: нет

Цитата
По поводу void* в качестве handle для Win32API — это ГОРАЗДО лучше, чем открытая структура у пользователя. Система должна сама заботится о защите своих объектов от несанкционированного вмешательства пользователя (да и от санкционированного тоже)

Спорный вопрос. Сколько *handle как проверить sizeof()? сколько я памяти использую?

Цитата
Далее, все серия Interlocked* в Win32API инлайнится компилятором, никаких dll не нужно (конечно, если программист не приложит больших усилий, что бы этого не было smile )

и как их сделать инлайн?

Цитата
В posix нет возможности ждать сразу на нескольких разных синхронизирующих примитивах.

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

Цитата
У Win32 это все же элегантнее — там можно ждать на самых разных событиях. Конечно это можно реализовать где угодно, но накладные расходы будут немаленькие smile

Профиль
Группа: Комодератор
Сообщений: 7045
Регистрация: 28.8.2007
Где: Химки, Московская обл

Репутация: 60
Всего: 223

Цитата
По поводу void* в качестве handle для Win32API — это ГОРАЗДО лучше, чем открытая структура у пользователя. Система должна сама заботится о защите своих объектов от несанкционированного вмешательства пользователя (да и от санкционированного тоже)
Цитата
Цитата
Далее, все серия Interlocked* в Win32API инлайнится компилятором, никаких dll не нужно (конечно, если программист не приложит больших усилий, что бы этого не было smile )
Код
#pragma intrinsic(_InterlockedIncrement)
Цитата
Цитата
У Win32 это все же элегантнее — там можно ждать на самых разных событиях. Конечно это можно реализовать где угодно, но накладные расходы будут немаленькие smile

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это! хранится весь мировой запас ссылок на документы, связанные с C++ 🙂
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе — для этого существует «Центр Помощи».

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »

[ Время генерации скрипта: 0.1407 ] [ Использовано запросов: 21 ] [ GZIP включён ]

Threads posix win32 что это

Система MinGW [1] часто используется как среда для исполнения утилит, пришедших с платформы Unix — make, gcc, g++ и т. д. Они нужны в первую очередь для компилирования приложений на платформе Windows с помощью бесплатных сред разработки (Eclipse, Dev-Cpp, wxDev-C++ и другие).

Есть порты MinGW для 32-битной и для 64-битной версий Windows. Установка 64-битной версии имеет несколько не очень понятных опций настройки, которые специально рассмотрены в этой статье.

[Процесс установки MinGW-W64 по шагам]

1. [2] -> Download -> mingw-w64-install.exe, запустите.

2. На первом экране появится приветствие мастера установки, просто Кликните Next.

MinGW W64 install01

3. Затем появляется важный экран настройки, где нужно выбрать опции системы.

MinGW W64 install02

Architecture: i686 или x86_64. Выберите x86_64, если у Вас современный процессор Athlon или Intel. Если у Вас старый Pentium Pro, Pentium II или Pentium III, то выберите i686.

Threads: posix или win32. Здесь выбирается GCC Threading model. Что выбрать — единого мнения нет. Если Вам нужно портировать сложные многопоточные приложения из Linux или FreeBSD, то возможно Вам лучше подойдет posix. Я обычно выбираю win32.

Exception: dwarf, sjlj или seh. Это относится к методике обработки ошибок. Состав выпадающего списка зависит от предыдущих опций.

Dwarf-2 EH. Реализация для Windows сама по себе не разработана для работы в условиях исполнения 64-битны приложений Windows. В режиме win32 вызываемый обработчик исключения не может распространяться на код, не совместимый со стандартом dw2; это означает, что любое исключение, которое происходит через любые «чужие фреймы» non-dw2 приведет к отказу, включая системные DLL Windows и DLL, встроенные в Visual Studio. Раскручивание кода Dwarf-2 в gcc включает инспектирование сборки x86, и оно не может происходить без соответствующей отладочной информации dwarf-2.

SjLj, SetJump LongJump. Этот метод обработки исключений работает в большинстве случаев на обоих платформах win32 и win64, за исключением сбоев общей защиты (general protection faults). Поддержка структурированной обработки ошибок разработана для gcc с целью преодолеть недостатки dw2 и sjlj. На платформе win64, информация отката размещается в секции xdata и в .pdata (таблица описания функции) вместо стека. Для win32 цепочка обработчиков сохраняется в стеке, и нуждается в сохранении/восстановлении с помощью реально выполняющегося кода.

GCC поддерживает два метода обработки исключений (EH):

DWARF-2 (DW2) EH, который требует наличия в выполняемом коде отладочной информации DWARF-2 (или DWARF-3). DW-2 EH может привести к некоторому разрастанию размера исполняемого кода, потому что в код добавляется большие таблицы отката по содержимому стека.

SJLJ. Этот метод базируется на setjmp/longjmp (SJLJ). Он несколько медленнее, чем DW2 EH (влияет даже на нормальное выполнение, когда не срабатывают исключения), однако он может работать поверх кода, который не был скомпилирован GCC, или в котором нет информации о истории вызовов через стек (call-stack unwinding information).

Structured Exception Handling (SEH). Windows использует свой собственный механизм обработки исключений, известный как Structured Exception Handling (SEH). К сожалению, GCC пока его не поддерживает. Однако обещается, что для x64 в появится поддержка SEH начиная с версии GCC 4.8.

Exception handling models of GCC site:stackoverflow.com
C++ Exception Handling for IA-64 site:static.usenix.org
EH newbies howto gcc.gnu.org
MinGW 64 bit Exception handling: SJLJ, DWARF, and SEH site:qt-project.org

Я выбрал для своей установки вариант seh.

4. На этом шаге нужно просто выбрать каталог установки. Оставьте все по умолчанию.

MinGW W64 install03

5. Запустится процесс закачки, который займет некоторое время.

MinGW W64 install04

По окончании загрузки нажмите Next и после окончания копирования Finish.

MinGW W64 install05

Если Вы хотите, чтобы утилиты из каталога c:Program Filesmingw-w64x86_64-4.9.2-win32-seh-rt_v3-rev1mingw64bin запускались без ввода полного пути, то добавьте этот каталог в пути поиска (в переменную окружения %Path%).

Содержание

  • 1. Что такое posix.exe?
  • 2. Posix.exe безопасно, или это вирус или вредоносная программа?
  • 3. Могу ли я удалить или удалить posix.exe?
  • 4. Распространенные сообщения об ошибках в posix.exe
  • 5. Как исправить posix.exe
  • 6. Обновление за февраль 2023
  • 7. Загрузите или переустановите posix.exe


Обновлено февраль 2023: Вот три шага к использованию инструмента восстановления для устранения проблем с exe на вашем компьютере: Получите его по адресу эту ссылку

  1. Скачайте и установите это программное обеспечение.
  2. Просканируйте свой компьютер на наличие проблем с exe.
  3. Исправьте ошибки exe с помощью программного инструмента

posix.exe это исполняемый файл, который является частью Microsoft Windows, разработанный Корпорация Microsoft, Версия программного обеспечения для Windows: 6.1.7601.17514 обычно 31952 в байтах, но у вас может отличаться версия.

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

Рекомендуется: Выявление ошибок, связанных с posix.exe
(опциональное предложение для Reimage — Cайт | Лицензионное соглашение | Персональные данные | Удалить)

Это posix.exe вирус или вредоносная программа?

Posix.exe безопасно, или это вирус или вредоносная программа?

Первое, что поможет вам определить, является ли тот или иной файл законным процессом Windows или вирусом, это местоположение самого исполняемого файла. Например, для posix.exe его путь будет примерно таким: C: Program Files Microsoft Corporation Microsoft Windows posix.exe

Чтобы определить его путь, откройте диспетчер задач, перейдите в «Просмотр» -> «Выбрать столбцы» и выберите «Имя пути к изображению», чтобы добавить столбец местоположения в диспетчер задач. Если вы обнаружите здесь подозрительный каталог, возможно, стоит дополнительно изучить этот процесс.

Еще один инструмент, который иногда может помочь вам обнаружить плохие процессы, — это Microsoft Process Explorer. Запустите программу (не требует установки) и активируйте «Проверить легенды» в разделе «Параметры». Теперь перейдите в View -> Select Columns и добавьте «Verified Signer» в качестве одного из столбцов.

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

Самые важные факты о posix.exe:

  • Имя: posix.exe
  • Программного обеспечения: Microsoft Windows,
  • Издатель: Корпорация Microsoft
  • Ожидаемое местоположение: C: Program Files Microsoft Corporation Microsoft Windows подпапке
  • Ожидаемый полный путь: C: Program Files Microsoft Corporation Microsoft Windows posix.exe
  • SHA1: 0003353A4957F2810F114F0101E1CD99AE9E582E
  • SHA256:
  • MD5: 3FB7AE65A2702C14DF2A2618966CEC62
  • Известно, что до 31952 размер байт в большинстве Windows;

Если у вас возникли какие-либо трудности с этим исполняемым файлом, перед удалением posix.exe следует определить, заслуживает ли он доверия. Для этого найдите этот процесс в диспетчере задач.

Найти его местоположение и сравнить размер и т. Д. С приведенными выше фактами

Если вы подозреваете, что можете быть заражены вирусом, вы должны немедленно попытаться это исправить. Чтобы удалить вирус posix.exe, необходимо скачайте и установите приложение полной безопасности, как это, Обратите внимание, что не все инструменты могут обнаружить все типы вредоносных программ, поэтому вам может потребоваться попробовать несколько вариантов, прежде чем вы добьетесь успеха.

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

Могу ли я удалить или удалить posix.exe?

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

Лучшая диагностика для этих подозрительных файлов — полный системный анализ с ASR Pro or это антивирус и средство для удаления вредоносных программ, Если файл классифицирован как вредоносный, эти приложения также удалят posix.exe и избавятся от связанных вредоносных программ.

Однако, если это не вирус, и вам нужно удалить posix.exe, вы можете удалить Microsoft Windows с вашего компьютера, используя его деинсталлятор. Если вы не можете найти его деинсталлятор, то вам может потребоваться удалить Microsoft Windows, чтобы полностью удалить posix.exe. Вы можете использовать функцию «Установка и удаление программ» на панели управления Windows.

  • 1. в Меню Пуск (для Windows 8 щелкните правой кнопкой мыши в нижнем левом углу экрана), нажмите Панель управления, а затем под Программы:
    o Windows Vista / 7 / 8.1 / 10: нажмите Удаление программы.
    o Windows XP: нажмите Установка и удаление программ.
  • 2. Когда вы найдете программу Microsoft Windows,щелкните по нему, а затем:
    o Windows Vista / 7 / 8.1 / 10: нажмите Удалить.
    o Windows XP: нажмите Удалить or Изменить / Удалить вкладка (справа от программы).
  • 3. Следуйте инструкциям по удалению Microsoft Windows,.

Распространенные сообщения об ошибках в posix.exe

Наиболее распространенные ошибки posix.exe, которые могут возникнуть:

• «Ошибка приложения posix.exe».
• «Ошибка posix.exe».
• «posix.exe столкнулся с проблемой и должен быть закрыт. Приносим извинения за неудобства».
• «posix.exe не является допустимым приложением Win32».
• «posix.exe не запущен».
• «posix.exe не найден».
• «Не удается найти posix.exe».
• «Ошибка запуска программы: posix.exe.»
• «Неверный путь к приложению: posix.exe.»

Эти сообщения об ошибках .exe могут появляться во время установки программы, во время выполнения связанной с ней программы Microsoft Windows, при запуске или завершении работы Windows, или даже при установке операционной системы Windows. Отслеживание момента появления ошибки posix.exe является важной информацией при устранении неполадок.

Как исправить posix.exe

Аккуратный и опрятный компьютер — это один из лучших способов избежать проблем с posix.exe. Это означает выполнение сканирования на наличие вредоносных программ, очистку жесткого диска cleanmgr и ПФС / SCANNOWудаление ненужных программ, мониторинг любых автозапускаемых программ (с помощью msconfig) и включение автоматических обновлений Windows. Не забывайте всегда делать регулярные резервные копии или хотя бы определять точки восстановления.

Если у вас возникла более серьезная проблема, постарайтесь запомнить последнее, что вы сделали, или последнее, что вы установили перед проблемой. Использовать resmon Команда для определения процессов, вызывающих вашу проблему. Даже в случае серьезных проблем вместо переустановки Windows вы должны попытаться восстановить вашу установку или, в случае Windows 8, выполнив команду DISM.exe / Online / Очистка-изображение / Восстановить здоровье, Это позволяет восстановить операционную систему без потери данных.

Чтобы помочь вам проанализировать процесс posix.exe на вашем компьютере, вам могут пригодиться следующие программы: Менеджер задач безопасности отображает все запущенные задачи Windows, включая встроенные скрытые процессы, такие как мониторинг клавиатуры и браузера или записи автозапуска. Единый рейтинг риска безопасности указывает на вероятность того, что это шпионское ПО, вредоносное ПО или потенциальный троянский конь. Это антивирус обнаруживает и удаляет со своего жесткого диска шпионское и рекламное ПО, трояны, кейлоггеры, вредоносное ПО и трекеры.

Обновлено февраль 2023:

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

  • Шаг 1: Скачать PC Repair & Optimizer Tool (Windows 10, 8, 7, XP, Vista — Microsoft Gold Certified).
  • Шаг 2: Нажмите «Начать сканирование”, Чтобы найти проблемы реестра Windows, которые могут вызывать проблемы с ПК.
  • Шаг 3: Нажмите «Починить все», Чтобы исправить все проблемы.

скачать
(опциональное предложение для Reimage — Cайт | Лицензионное соглашение | Персональные данные | Удалить)

Загрузите или переустановите posix.exe

Вход в музей Мадам Тюссо не рекомендуется загружать заменяемые exe-файлы с любых сайтов загрузки, так как они могут содержать вирусы и т. д. Если вам нужно скачать или переустановить posix.exe, мы рекомендуем переустановить основное приложение, связанное с ним. Microsoft Windows,.

Основные возможности 5 в Windows 10

  1. Новое меню Пуск. Microsoft вернула меню «Пуск».
  2. Интеграция с Кортаной. Windows 10 перенесет на настольные компьютеры цифрового помощника Microsoft Cortana с голосовым управлением, чтобы вам было проще взаимодействовать с устройством, не отрывая пальца.
  3. Веб-браузер Microsoft Edge.
  4. Виртуальные рабочие столы.
  5. Универсальные приложения.

19 Апрель, 2017

Информация об операционной системе

Ошибки posix.exe могут появляться в любых из нижеперечисленных операционных систем Microsoft Windows:

  • Windows 10
  • Windows 8.1
  • Windows 7
  • Windows Vista
  • Windows XP
  • Windows ME
  • Windows 200

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

В этой статье мы познакомимся с POSIX Threads для того, чтобы затем узнать как это все работает в Linux. Не заходя в дебри синхронизации и сигналов, рассмотрим основные элементы Pthreads. Итак, под капотом потоки.

Общие сведения

Множественные нити исполнения в одном процессе называют потоками и это базовая единица загрузки ЦПУ, состоящая из идентификатора потока, счетчика, регистров и стека. Потоки внутри одного процесса делят секции кода, данных, а также различные ресурсы: описатели открытых файлов, учетные данные процесса сигналы, значения umask, nice, таймеры и прочее.

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

В чем польза множественных потоков исполнения? Возьмем какой-нибудь загруженный веб сервер, например habrahabr.ru. Если бы сервер создавал отдельный процесс для обслуживания каждого http запроса, мы бы ожидали вечно пока загрузится наша страница. Создания нового процесса — дорогостоящее удовольствие для ОС. Даже учитывая оптимизацию за счет копирования при записи, системные вызовы fork и exec создают новые копии страниц памяти и списка файловых описателей. В целом ядро ОС может создать новый поток на порядок быстрее, чем новый процесс.

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

Таблицы страниц до и после изменения общей страницы памяти во время копирования при записи.

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

Закон Амдаля для распараллеливания процессов.

Используя уравнение, показанное на рисунке, можно вычислить максимальное улучшение производительности системы, использующей N процессоров и фактор F, который указывает, какая часть системы не может быть распараллелена. Например 75% кода запускается параллельно, а 25% — последовательно. В таком случае на двухядерном процессоре будет достигнуто 1.6 кратное ускорение программы, на четырехядерном процессоре — 2.28571 кратное, а предельное значение ускорения при N стремящемся к бесконечности равно 4.

Отображение потоков в режим ядра

Практически все современные ОС — включая Windows, Linux, Mac OS X, и Solaris — поддерживают управление потоками в режиме ядра. Однако потоки могут быть созданы не только в режиме ядра, но и в режиме пользователя. При использовании этого уровня ядро не знает о существовании потоков — все управление потоками реализуется приложением с помощью специальных библиотек. Пользовательские потоки по разному отображаются на потоки в режиме ядра. Всего существует три модели, из которых 1:1 является наиболее часто используемой.

Отображение N:1

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

Отображение 1:1

Это самая проста модель, в которой каждый поток созданный в каком-нибудь процессе непосредственно управляется планировщиком ядра ОС и отображается на один единственный поток в режиме ядра. Чтобы приложение не плодило бесконтрольно потоки, перегружая ОС, вводят ограничение на максимальное количество потоков поддерживаемых в ОС. Данный способ отображения потоков поддерживают ОС Linux и Windows.

Отображение M:N

При таком подходе M пользовательских потоков мультиплексируются в такое же или меньшее N количество потоков ядра. Преодолеваются негативные эффекты двух других моделей: нити по-настоящему исполняются параллельно и нет необходимости в ОС вводить ограничения на их общее количество. Вместе с тем данную модель довольно трудно реализовать с точки зрения программирования.

Потоки POSIX

В конце 1980-х и начале 1990-х было несколько разных API, но в 1995 г. POSIX.1c стандартизовал потоки POSIX, позже это стало частью спецификаций SUSv3. В наше время многоядерные процессоры проникли даже в настольные ПК и смартфоны, так что у большинства машин есть низкоуровневая аппаратная поддержка, позволяющая им одновременно выполнять несколько потоков. В былые времена одновременное исполнение потоков на одноядерных ЦПУ было лишь впечатляюще изобретательной, но очень эффективной иллюзией.

Pthreads определяет набор типов и функций на Си.

  • pthread_t — идентификатор потока;
  • pthread_mutex_t — мютекс;
  • pthread_mutexattr_t — объект атрибутов мютекса
  • pthread_cond_t — условная переменная
  • pthread_condattr_t — объект атрибута условной переменной;
  • pthread_key_t — данные, специфичные для потока;
  • pthread_once_t — контекст контроля динамической инициализации;
  • pthread_attr_t — перечень атрибутов потока.

В традиционном Unix API код последней ошибки errno является глобальной int переменной. Это однако не годится для программ с множественными нитями исполнения. В ситуации, когда вызов функции в одном из исполняемых потоков завершился ошибкой в глобальной переменной errno, может возникнуть состояние гонки из-за того, что и остальные потоки могут в данный момент проверять код ошибки и оконфузиться. В Unix и Linux эту проблему обошли тем, что errno определяется как макрос, задающий для каждой нити собственное изменяемое lvalue.

Из man errno
Переменная errno определена в стандарте ISO C как изменяемое lvalue int и не объявляемая явно; errno может быть и макросом. Переменная errno является локальным значением нити; её изменение в одной нити не влияет на её значение в другой нити.

Создание потока

В начале создается потоковая функция. Затем новый поток создается функцией pthread_create(), объявленной в заголовочном файле pthread.h. Далее, вызывающая сторона продолжает выполнять какие-то свои действия параллельно потоковой функции.

#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start)(void *), void *arg);

При удачном завершении pthread_create() возвращает код 0, ненулевое значение сигнализирует об ошибке.

  • Первый параметр вызова pthread_create() является адресом для хранения идентификатора создаваемого потока типа pthread_t.
  • Аргумент start является указателем на потоковую void * функцию, принимающей бестиповый указатель в качестве единственной переменной.
  • Аргумент arg — это бестиповый указатель, содержащий аргументы потока. Чаще всего arg указывает на глобальную или динамическую переменную, но если вызываемая функция не требует наличия аргументов, то в качестве arg можно указать NULL.
  • Аргумент attr также является бестиповым указателем атрибутов потока pthread_attr_t. Если этот аргумент равен NULL, то поток создается с атрибутами по умолчанию.

Рассмотрим теперь пример многопоточной программы.

#include <pthread.h>
#include <stdio.h>

int count; /* общие данные для потоков */
int atoi(const char *nptr);
void *potok(void *param); /* потоковая функция */

int main(int argc, char *argv[])
{
  pthread_t tid; /* идентификатор потока */
  pthread_attr_t attr; /* отрибуты потока */

if (argc != 2) {
  fprintf(stderr,"usage: progtest <integer value>n");
  return -1;
}

if (atoi(argv[1]) < 0) {
  fprintf(stderr,"Аргумент %d не может быть отрицательным числомn",atoi(argv[1]));
  return -1;
}

/* получаем дефолтные значения атрибутов */
  pthread_attr_init(&attr);

/* создаем новый поток */
  pthread_create(&tid,&attr,potok,argv[1]);

/* ждем завершения исполнения потока */
  pthread_join(tid,NULL);
  printf("count = %dn",count);
}

/* Контроль переходит потоковой функции */
void *potok(void *param) 
{
  int i, upper = atoi(param);
  count = 0;

  if (upper > 0) {
    for (i = 1; i <= upper; i++)
    count += i;
  }

  pthread_exit(0);
}

Чтобы подключить библиотеку Pthread к программе, нужно передать компоновщику опцию -lpthread.

gcc -o progtest -std=c99 -lpthread progtest.c

О присоединении потока pthread_join расскажу чуть позже. Строка pthread_t tid задает идентификатор потока. Атрибуты функции задает pthread_attr_init(&attr). Так как мы не задавали их явно, будут использованы значения по умолчанию.

Завершение потока

Поток завершает выполнение задачи когда:

  • потоковая функция выполняет return и возвращает результат произведенных вычислений;
  • в результате вызова завершения исполнения потока pthread_exit();
  • в результате вызова отмены потока pthread_cancel();
  • одна из нитей совершает вызов exit()
  • основная нить в функции main() выполняет return, и в таком случае все нити процесса резко сворачиваются.

Синтаксис проще, чем при создании потока.

#include <pthread.h>
void pthread_exit(void *retval);

Если в последнем варианте старшая нить из функции main() выполнит pthread_exit() вместо просто exit() или return, то тогда остальные нити продолжат исполняться, как ни в чем не бывало.

Ожидание потока

Функция pthread_join() ожидает завершения потока обозначенного THREAD_ID. Если этот поток к тому времени был уже завершен, то функция немедленно возвращает значение. Смысл функции в том, чтобы синхронизировать потоки. Она объявлена в pthread.h следующим образом:

#include <pthread.h>
int pthread_join (pthread_t THREAD_ID, void ** DATA);

При удачном завершении pthread_join() возвращает код 0, ненулевое значение сигнализирует об ошибке.

Если указатель DATA отличается от NULL, то туда помещаются данные, возвращаемые потоком через функцию pthread_exit() или через инструкцию return потоковой функции. Несколько потоков не могут ждать завершения одного. Если они пытаются выполнить это, один поток завершается успешно, а все остальные — с ошибкой ESRCH. После завершения pthread_join(), пространство стека связанное с потоком, может быть использовано приложением.

В каком-то смысле pthread_joini() похожа на вызов waitpid(), ожидающую завершения исполнения процесса, но с некоторыми отличиями. Во-первых, все потоки одноранговые, среди них отсутствует иерархический порядок, в то время как процессы образуют дерево и подчинены иерархии родитель — потомок. Поэтому возможно ситуация, когда поток А, породил поток Б, тот в свою очередь заделал В, но затем после вызова функции pthread_join() А будет ожидать завершения В или же наоборот. Во-вторых, нельзя дать указание одному ожидай завершение любого потока, как это возможно с вызовом waitpid(-1, &status, options). Также невозможно осуществить неблокирующий вызов pthread_join().

Досрочное завершение потока

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

int pthread_cancel (pthread_t THREAD_ID);

При удачном завершении pthread_cancel() возвращает код 0, ненулевое значение сигнализирует об ошибке.

Важно понимать, что несмотря на то, что pthread_cancel() возвращается сразу и может завершить поток досрочно, ее нельзя назвать средством принудительного завершения потоков. Дело в том, что поток не только может самостоятельно выбрать момент завершения в ответ на вызов pthread_cancel(), но и вовсе его игнорировать. Вызов функции pthread_cancel() следует рассматривать как запрос на выполнение досрочного завершения потока. Поэтому, если для вас важно, чтобы поток был удален, нужно дождаться его завершения функцией pthread_join().

Небольшая иллюстрация создания и отмены потока.

pthread_t tid;

/* создание потока */
pthread_create(&tid, 0, worker, NULL);
…
/* досрочное завершение потока */
pthread_cancel(tid);

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

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

while (1) {
  /* чего-то там делаем */
  /* пам-парам-пам-пам */
  /* не пора-ли сворачиваться? */

  pthread_testcancel();
}

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

Любому потоку по умолчанию можно присоединиться вызовом pthread_join() и ожидать его завершения. Однако в некоторых случаях статус завершения потока и возврат значения нам не интересны. Все, что нам надо, это завершить поток и автоматически выгрузить ресурсы обратно в распоряжение ОС. В таких случаях мы обозначаем поток отсоединившимся и используем вызов pthread_detach().

#include <pthread.h>
int pthread_detach(pthread_t thread);

При удачном завершении pthread_detach() возвращает код 0, ненулевое значение сигнализирует об ошибке.

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

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

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

В начальной части статьи мы уже указывали на эти преимущество, поэтому вкратце их просто перечислим.

  • Потоки довольно просто обмениваются данными по сравнению с процессами.
  • Создавать потоки для ОС проще и быстрее, чем создавать процессы.

Теперь немного о недостатках.

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

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

Использованные материалы и дополнительная информация

  1. Michael Kerrisk The Linux Programming Interface.
  2. Abraham Silberschatz, Peter B. Galvin Greg Gagne, Operating System Concepts 9-th ed.
  3. Николай Иванов Самоучитель программирования в Linux 2-е издание.
  4. Эндрю Таненбаум Архитектура компьютера.

POSIX Threads — стандарт POSIX реализации потоков (нитей) выполнения, определяющий API для создания и управления ими.

Библиотеки, реализующие этот стандарт (и функции этого стандарта), обычно называются Pthreads (функции имеют приставку «pthread_»). Хотя наиболее известны варианты для Unix-подобных операционных систем, таких как Linux или Solaris, но существует и реализация для Microsoft Windows (Pthreads-w32)

Основные функции стандарта

Pthreads определяет набор типов и функций на языке программирования Си. Заголовочный файл — pthread.h.

  • Типы данных:
    • pthread_t: дескриптор потока
    • pthread_attr_t: перечень атрибутов потока
  • Функции управления потоками:
    • pthread_create(): создание потока
    • pthread_exit(): завершение потока (должна вызываться функцией потока при завершении)
    • pthread_cancel(): отмена потока
    • pthread_join(): подключиться к другому потоку и ожидать его завершения; поток, к которому необходимо подключиться, должен быть создан с возможностью подключения (PTHREAD_CREATE_JOINABLE)
    • pthread_detach(): отключиться от потока, сделав его при этом отдельным (PTHREAD_CREATE_DETACHED)
    • pthread_attr_init(): инициализировать структуру атрибутов потока
    • pthread_attr_setdetachstate(): указывает параметр «отделимости» потока (detach state), который говорит о возможности подключения к нему (при помощи pthread_join) других потоков (значение PTHREAD_CREATE_JOINABLE) для ожидания окончания или о запрете подключения (значение PTHREAD_CREATE_DETACHED); ресурсы отдельного потока (PTHREAD_CREATE_DETACHED) при завершении автоматически освобождаются и возвращаются системе
    • pthread_attr_destroy(): освободить память от структуры атрибутов потока (уничтожить дескриптор)
  • Функции синхронизации потоков:
    • pthread_mutex_init(), pthread_mutex_destroy(), pthread_mutex_lock(), pthread_mutex_trylock(), pthread_mutex_unlock(): с помощью мьютексов
    • pthread_cond_init(), pthread_cond_signal(), pthread_cond_wait(): с помощью условных переменных

Пример

Пример использования потоков на языке C:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
 
static void wait_thread(void)
{
    time_t start_time = time(NULL);
 
    while (time(NULL) == start_time)
    {
        /* do nothing except chew CPU slices for up to one second. */
    }
}
 
static void *thread_func(void *vptr_args)
{
    int i;
 
    for (i = 0; i < 20; i++)
    {
        fputs("  bn", stderr);
        wait_thread();
    }
 
    return NULL;
}
 
int main(void)
{
    int i;
    pthread_t thread;
 
    if (pthread_create(&thread, NULL, thread_func, NULL) != 0)
    {
        return EXIT_FAILURE;
    }
 
    for (i = 0; i < 20; i++)
    {
        puts("a");
        wait_thread();
    }
 
    if (pthread_join(thread, NULL) != 0)
    {
        return EXIT_FAILURE;
    }
 
    return EXIT_SUCCESS;
}

Пример использования потоков на языке C++:

#include <cstdlib>
#include <iostream>
#include <memory>
 
#include <pthread.h>
 
class Thread
{
private:
    pthread_t thread;
 
    Thread(const Thread& copy);         // copy constructor denied
    static void *thread_func(void *d)   { ((Thread *)d)->run(); }
 
public:
    Thread()             {}
    virtual ~Thread()    {}
 
    virtual void run() = 0;
 
    int start()          { return pthread_create(&thread, NULL,
                           Thread::thread_func, (void*)this); }
    int wait ()          { return pthread_join  (thread, NULL); }
};
 
typedef std::auto_ptr<Thread> ThreadPtr;
 
int main(void)
{
    class Thread_a:public Thread
    {
    public:
        void run()
        {
            for (int i=0; i<20; i++, sleep(1))
                std::cout << "a  " << std::endl;
        }
    };
 
    class Thread_b:public Thread
    {
    public:
        void run()
        {
            for(int i=0; i<20; i++, sleep(1))
                std::cout << "  b" << std::endl;
        }
    };
 
    ThreadPtr a( new Thread_a() );
    ThreadPtr b( new Thread_b() );
 
    if (a->start() != 0 || b->start() != 0)
        return EXIT_FAILURE;
 
    if (a->wait() != 0 || b->wait() != 0)
        return EXIT_FAILURE;
 
    return EXIT_SUCCESS;
}

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

Отличие состоит в том, что программа на C создает один новый поток для печати ‘b’, а основной поток печатает ‘a’. Основной поток (после печати ‘aaaaa….’) ждёт завершения дочернего потока.

Программа на C++ создает два новых потока, один печатает ‘a’, второй, соответственно, — ‘b’. Основной поток ждёт завершения обоих дочерних потоков.

См. также

  • Native POSIX Thread Library (NPTL)
  • GNU Portable Threads
  • Список многопоточных библиотек C++

Ссылки

  • Спецкурс «Многонитевое программирование» ВМиК МГУ  (рус.)
  • Многопоточное программирование (Учебник Pthreads)  (англ.)
  • Примеры использования Pthreads  (англ.)
  • Примеры использования Pthreads в C/C++  (англ.)
  • Статья «Объясняя потоки POSIX», Даниэля Роббинса (основателя проекта Gentoo)  (англ.)
  • Интервью «10 вопросов Девиду Бутенхофу о параллельном программировании и потоках POSIX» с Майклом Суиссом  (англ.)
  • The Open Group Base Specifications Issue 6, IEEE Std 1003.1  (англ.)
  • Pthread Win-32, Basic Programming (англ.)
  • Pthreads Tutorial (англ.)
  • C/C++ Tutorial: using Pthreads (англ.)
  • Article «POSIX threads explained» by Daniel Robbins (Gentoo Linux founder) (англ.)
  • Interview «Ten Questions with David Butenhof about Parallel Programming and POSIX Threads» by Michael Suess (англ.)
  • Open Source POSIX Threads for Win32 (англ.)
  • The Open Group Base Specifications Issue 6, IEEE Std 1003.1 (англ.)
  • GNU Portable threads (англ.)
  • Flash Presentation on pThread (англ.)
  • Pthreads Presentation at 2007 OSCON (O’Reilly Open Source Convention) by Adrien Lamothe. An overview of Pthreads with current trends. (англ.)

Содержание

  1. POSIX Threads
  2. Содержание
  3. Основные функции стандарта
  4. Пример
  5. См. также
  6. Ссылки
  7. Смотреть что такое «POSIX Threads» в других словарях:
  8. Национальная библиотека им. Н. Э. Баумана
    Bauman National Library
  9. Персональные инструменты
  10. POSIX Threads
  11. Содержание
  12. Причины использования потоков
  13. Основные функции
  14. Мьютексы в пакете Pthreads
  15. Условные переменные
  16. Блокировка чтения-записи
  17. Барьеры
  18. Спинлок
  19. Заключение
  20. Pthreads: Потоки в русле POSIX
  21. Общие сведения
  22. Отображение потоков в режим ядра
  23. Потоки POSIX
  24. Создание потока
  25. Завершение потока
  26. Ожидание потока
  27. Досрочное завершение потока
  28. Отсоединение потока
  29. Потоки versus процессы
  30. Posix win threads for windows что это
  31. Видео

POSIX Threads

POSIX Threads — стандарт POSIX реализации потоков (нитей) выполнения, определяющий API для создания и управления ими.

Библиотеки, реализующие этот стандарт (и функции этого стандарта), обычно называются Pthreads (функции имеют приставку «pthread_»). Хотя наиболее известны варианты для Unix-подобных операционных систем, таких как Linux или Solaris, но существует и реализация для Microsoft Windows (Pthreads-w32)

Содержание

Основные функции стандарта

Pthreads определяет набор типов и функций на языке программирования Си. Заголовочный файл — pthread.h.

Пример

Пример использования потоков на языке C:

Пример использования потоков на языке C++:

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

Отличие состоит в том, что программа на C создает один новый поток для печати ‘b’, а основной поток печатает ‘a’. Основной поток (после печати ‘aaaaa….’) ждёт завершения дочернего потока.

Программа на C++ создает два новых потока, один печатает ‘a’, второй, соответственно, — ‘b’. Основной поток ждёт завершения обоих дочерних потоков.

См. также

Ссылки

Смотреть что такое «POSIX Threads» в других словарях:

POSIX Threads — is a POSIX standard for threads. The standard defines an API for creating and manipulating threads.Libraries implementing the POSIX Threads standard are often named Pthreads. Pthreads are most commonly used on Unix like POSIX systems such as… … Wikipedia

POSIX — (IPAEng|ˈpɒzɪks) or Portable Operating System Interface cite web | title = POSIX | url = http://standards.ieee.org/regauth/posix/ | work = Standards | publisher = IEEE] is the collective name of a family of related standards specified by the IEEE … Wikipedia

POSIX — est le nom d une famille de standards définie depuis 1988 par l Institute of Electrical and Electronics Engineers et formellement désignée IEEE 1003. Ces standards ont émergé d un projet de standardisation des API des logiciels destinés à… … Wikipédia en Français

Posix — est le nom d une famille de standards définie depuis 1988 par l IEEE et formellement désignée IEEE 1003. Ces standards ont émergé d un projet de standardisation des API des logiciels destinés à fonctionner sur des variantes du système d… … Wikipédia en Français

POSIX — es el acrónimo de Portable Operating System Interface; la X viene de UNIX como seña de identidad de la API. El término fue sugerido por Richard Stallman en respuesta a la demanda de la IEEE, que buscaba un nombre fácil de recordar. Una traducción … Wikipedia Español

Поток POSIX — POSIX Threads стандарт потоков (нитей) выполнения, определяющий API для создания и управления ими. Библиотеки, реализующие этот стандарт (и функции этого стандарта), обычно называются Pthreads (функции имеют приставку «pthread »). Хотя наиболее… … Википедия

Native POSIX Thread Library — Die Native POSIX Thread Library (NPTL) ist eine moderne Implementierung einer Threading Bibliothek für Linux. Sie wird in Verbindung mit der GNU C Library (glibc) verwendet und erlaubt Linux Programmen die Verwendung von POSIX Threads (pthreads) … Deutsch Wikipedia

Native POSIX Thread Library — The Native POSIX Thread Library (NPTL) is a software feature that enables the Linux kernel to run programs written to use POSIX Threads efficiently. Contents 1 History 2 Design 3 See also 4 References … Wikipedia

GNU Portable Threads — Infobox Software name = GNU Portable Threads developer = Ralf S. Engelschall latest release version = 2.0.7 latest release date = 8 June 2006 operating system = UNIX genre = Runtime library license = LGPL website =… … Wikipedia

Источник

Национальная библиотека им. Н. Э. Баумана
Bauman National Library

Персональные инструменты

POSIX Threads

Communications protocol
Purpose позволяет программе контролировать множество разных потоков, накладывающихся во время
Developer(s) POSIX.1c, Threads extensions (IEEE Std 1003.1c-1995)
Introduced 1995 ; 26 years ago ( 1995 )
Based on C
Influenced POSIX 1003.1-2001

POSIX Threads

Содержание

Причины использования потоков

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

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

Вторым аргументом в пользу потоков является легкость (то есть быстрота) их создания и ликвидации по сравнению с более «тяжеловесными» процессами. Во многих системах создание потоков осуществляется в 10–100 раз быстрее, чем создание процессов. Это свойство особенно пригодится, когда потребуется быстро и динамично изменять количество потоков. [Источник 1]

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

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

Основные функции

В стандарте определено более 60 вызовов функций. Они могут быть разделены на 4 категории:

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

Вызовы, связанные с потоком Описание
pthread_create Создание нового потока
pthread_exit Завершение работы вызвавшего потока
pthread_join Ожидание выхода из указанного потока
pthread_yield Освобождение центрального процессора, позволяющее

выполняться другому потоку

pthread_attr_init Создание и инициализация структуры атрибутов потока
pthread_attr_destroy Удаление структуры атрибутов потока

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

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

Чтобы лучше понять, как работают функции пакета Pthread, рассмотрим простой пример, показанный ниже. Основная программа этого примера работает в цикле столько раз, cколько указано в константе NUMBER_OF_THREADS (количество потоков), создавая при каждой итерации новый поток и предварительно сообщив о своих намерениях. Если создать поток не удастся, она выводит сообщение об ошибке и выполняет выход. После создания всех потоков осуществляется выход из основной программы. При создании поток выводит однострочное сообщение, объявляя о своем существовании, после чего осуществляет выход. Порядок, в котором выводятся различные сообщения, не определен и при нескольких запусках программы может быть разным.

Мьютексы в пакете Pthreads

pthread_mutex_init Создание мьютекса
pthread_mutex_destroy Уничтожение существующего мьютекса
pthread_mutex_lock Овладение блокировкой или блокирование потока
pthread_mutex_trylock Овладение блокировкой или выход с ошибкой
pthread_mutex_unlock Разблокирование

Условные переменные

Наиболее важные вызовы, связанные с условными переменными, показаны в таблице. В ней представлены вызовы, предназначенные для создания и уничтожения условных переменных.

Вызов из потока Описание
pthread_cond_init Создание условной переменной
pthread_cond_destroy Уничтожение условной переменной
pthread_cond_wait Блокировка в ожидании сигнала
pthread_cond_signal Сигнализирование другому потоку и его активизация
pthread_cond_broadcast Сигнализирование нескольким потокам и активизация всех этих потоков

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

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

Блокировка чтения-записи

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

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

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

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

Барьеры

Где последний параметр count задает число нитей, которые должны дойти до барьера (вызвать функцию pthread_barrier_wait ) прежде чем они смогут продолжить выполнение. Раз существует функция инициализирующая барьер, то существует и комплиментарная функция которая уничтожает его:

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

Спинлок

Третий примитив синхронизации, про который хотелось бы поговорить это spin lock(спинлок). С точки зрения функциональности этот примитив ничем не отличается от мьютекса. Основная стоящая за ними идея состоит в том, чтобы вместо того чтобы заблокировать нить в случае если блокировка уже захвачена, крутиться, проверяя не освободилась ли блокировка (отсюда и слово spin в названии). Фактически спинлок это мьютекс основанный на использовании активного ожидания. Какой тогда смысл в таком примитиве? В случае если мы имеем мультипроцессор (так как на однопроцессорной машине спинлок будет бесполезно съедать циклы процессора до тех пор, пока не произойдет переключение на другую владеющую блокировкой нить) и крайне малый размер критической секции защищаемой этим примитивом (чтобы опять же не ждать долго и снизить опасность переключения на другую нить) спинлок может быть использован эффективнее чем мьютекс. Это обусловлено тем что он не вызывает долгой операции перевода нити в сон, вообще считается что spin lock реализуется на основе самых быстрых механизмов синхронизации доступных в системе. В случае если какое-либо из двух вышеприведенных условий нарушается, спинлок не даст выигрыша в производительности и выгоднее воспользоваться мьютексом. Согласно стандарту данный примитив представляется при помощи типа pthread_spinlock_t и набора операций над ним, которые практически совпадают с соответствующими операциями для мьютекса:

Заключение

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

Источник

Pthreads: Потоки в русле POSIX

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

Posix win threads for windows что это

В этой статье мы познакомимся с POSIX Threads для того, чтобы затем узнать как это все работает в Linux. Не заходя в дебри синхронизации и сигналов, рассмотрим основные элементы Pthreads. Итак, под капотом потоки.

Общие сведения

Posix win threads for windows что это

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

В чем польза множественных потоков исполнения? Возьмем какой-нибудь загруженный веб сервер, например habrahabr.ru. Если бы сервер создавал отдельный процесс для обслуживания каждого http запроса, мы бы ожидали вечно пока загрузится наша страница. Создания нового процесса — дорогостоящее удовольствие для ОС. Даже учитывая оптимизацию за счет копирования при записи, системные вызовы fork и exec создают новые копии страниц памяти и списка файловых описателей. В целом ядро ОС может создать новый поток на порядок быстрее, чем новый процесс.

Posix win threads for windows что это

Таблицы страниц до и после изменения общей страницы памяти во время копирования при записи.

Posix win threads for windows что это

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

Закон Амдаля для распараллеливания процессов.

Posix win threads for windows что это

Используя уравнение, показанное на рисунке, можно вычислить максимальное улучшение производительности системы, использующей N процессоров и фактор F, который указывает, какая часть системы не может быть распараллелена. Например 75% кода запускается параллельно, а 25% — последовательно. В таком случае на двухядерном процессоре будет достигнуто 1.6 кратное ускорение программы, на четырехядерном процессоре — 2.28571 кратное, а предельное значение ускорения при N стремящемся к бесконечности равно 4.

Отображение потоков в режим ядра

Практически все современные ОС — включая Windows, Linux, Mac OS X, и Solaris — поддерживают управление потоками в режиме ядра. Однако потоки могут быть созданы не только в режиме ядра, но и в режиме пользователя. При использовании этого уровня ядро не знает о существовании потоков — все управление потоками реализуется приложением с помощью специальных библиотек. Пользовательские потоки по разному отображаются на потоки в режиме ядра. Всего существует три модели, из которых 1:1 является наиболее часто используемой.

Отображение N:1

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

Posix win threads for windows что это

Отображение 1:1

Это самая проста модель, в которой каждый поток созданный в каком-нибудь процессе непосредственно управляется планировщиком ядра ОС и отображается на один единственный поток в режиме ядра. Чтобы приложение не плодило бесконтрольно потоки, перегружая ОС, вводят ограничение на максимальное количество потоков поддерживаемых в ОС. Данный способ отображения потоков поддерживают ОС Linux и Windows.

Posix win threads for windows что это

Отображение M:N

При таком подходе M пользовательских потоков мультиплексируются в такое же или меньшее N количество потоков ядра. Преодолеваются негативные эффекты двух других моделей: нити по-настоящему исполняются параллельно и нет необходимости в ОС вводить ограничения на их общее количество. Вместе с тем данную модель довольно трудно реализовать с точки зрения программирования.

Posix win threads for windows что это

Потоки POSIX

В конце 1980-х и начале 1990-х было несколько разных API, но в 1995 г. POSIX.1c стандартизовал потоки POSIX, позже это стало частью спецификаций SUSv3. В наше время многоядерные процессоры проникли даже в настольные ПК и смартфоны, так что у большинства машин есть низкоуровневая аппаратная поддержка, позволяющая им одновременно выполнять несколько потоков. В былые времена одновременное исполнение потоков на одноядерных ЦПУ было лишь впечатляюще изобретательной, но очень эффективной иллюзией.

Pthreads определяет набор типов и функций на Си.

Из man errno
Переменная errno определена в стандарте ISO C как изменяемое lvalue int и не объявляемая явно; errno может быть и макросом. Переменная errno является локальным значением нити; её изменение в одной нити не влияет на её значение в другой нити.

Создание потока

При удачном завершении pthread_create() возвращает код 0, ненулевое значение сигнализирует об ошибке.

Рассмотрим теперь пример многопоточной программы.

Завершение потока

Поток завершает выполнение задачи когда:

Синтаксис проще, чем при создании потока.

Ожидание потока

При удачном завершении pthread_join() возвращает код 0, ненулевое значение сигнализирует об ошибке.

Досрочное завершение потока

При удачном завершении pthread_cancel() возвращает код 0, ненулевое значение сигнализирует об ошибке.

Небольшая иллюстрация создания и отмены потока.

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

Posix win threads for windows что это

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

При удачном завершении pthread_detach() возвращает код 0, ненулевое значение сигнализирует об ошибке.

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

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

В начальной части статьи мы уже указывали на эти преимущество, поэтому вкратце их просто перечислим.

Теперь немного о недостатках.

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

Источник

Posix win threads for windows что это

Профиль
Группа: Участник
Сообщений: 44
Регистрация: 6.2.2009

Репутация: нет
Всего: нет

И так в бою за титул чемпиона участвует два соперника
Win32Api(будем его так кликать):
OS: Windows NT/95/98/me/2000/xp/vista/seven/ce(может не в той последовательности)

POSIX:
OS: Unix/Linux(many)/Mac OS/QNX/(слышал про реализацию под Windows NT/95/98/me/2000/xp/vista/seven/ce правда уже не в комплекте).

Let’s Begin(Давайте начнем)

1)Round «Mutual blocking(взаимо блокировка)»:

Win32Api представляет CRITICAL_SECTION и и Mutex.
POSIX уверенно говорит о Mutex.

Win32Api:
CRITICAL_SECTION
InitializeCriticalSection();
EnterCriticalSection();
TryEnterCritticalSection();
LeaveCriticalSection();
DeleteCriticalSection();

Просты в использовании, выходят в режим ядра когда это действительно нужно. Из минусов можно сказать большой расход памяти(из-за структуры).
Требуют обработку исключений(по крайней мере InitializeCriticalSection,
а если я использую С, __try __catch __finally вообщем расклад то не очень)
-Распростроняются только на один процесс(хотя при желании можно и изменить, мы ведь знаем что в структуре есть handle семафора, но
наверное не стоит)
Mutex:
CreateMutex();
OpenMutex();
WaitForSingleObject();
WaitForMultiObjects();
ReleaseMutex();
CloseHandle();

Mutex:
pthread_mutex_init();
pthread_mutex_lock();
pthread_mutex_trylock();
pthread_mutex_unlock();
pthread_mutex_destroy();

Открытая структура, выходят в режим ядра когда это действительно нужно. Распростроняются только на один процесс. Нет возможности ожидания
больше одного mutexю
Кто победил? Трудновато сказать. Тут все завист от то кто что ожидает при использовании «Mutual blocking(взаимо блокировка)». Лично мое мнение это Win32Api.

2)Round «Semaphore»:
Win32Api:
CreateSemaphore();
WaitForSingleObject();
WaitForMultiObjects();
ReleaseSemaphore();
CloseHandle();

В принципе все приимущества что и у Mutex. Не стоит думать как был создан(или же был открыт) семафор при уничтожении. Пожалуй не удобно при открытии
делать дубликацию HANDL.
Posix:
sem_init();
sem_wait();
sem_post();
sem_trywait();
sem_getvalue();
sem_destory();
sem_open();
sem_close();
sem_unlink();
Надо помнить как все же был создан(или был открыт) семафор при уничтожении. Приимучество можно получить счетчик, и есть try wait.

Думаю здесь честно победу можно отдать Win32Api.
Так что счет 2:0

3)Round «Atomic operation or Interlocked(Атомарные операции или Interlocked(мне не нравится перевод))»

Win32Api:
InterlockedDecrement();
InterlockedIncrement();
InterlockedAdd();
Ну и в таком духе.
Приимуществ нет. Не достаток вызывают DLL, соответственно заинлайнится не смогут(может есть какаета другая реализация?).

Posix(не слышал так что воспользуемся linux):
atomic_add();
atomic_sub();
atomic_inc();
atomic_dec();

Инлайнятся.
Говорить о assembler думаю не стоит, но если говорить то легче реализовывать под винду.
Раунд за Linux;
Так что счет 2:1.

4)Round «Thread local storage»

Win32Api:
TlsAlloc();
TlsSetValue();
TlsGetValue();
TlsFree();
Без коментариев.
Posix:
pthread_create_key();
pthread_setspecific();
pthread_getspecific();
pthread_delete_key();
Без коментариев.

В это раунде нечья.

Я бы сказал не чего особого. Только вот не понятно как уничтожать.
Posix:
pthread_cond_init()
pthread_cond_wait();
pthread_cond_timedwait();
pthread_cond_signal();
pthread_cond_broadcast();
pthread_cond_destroy();

Функция с ожиданием по времени.
Так что Posix +1;

Win32Api не имеет барьеров. Создание управление потоками не лучше чем у POSIX, CreateThread/_beginthread/_beginthreadEx по мне менее удобны чем pthread_create,
Хотя бы по тому что параметров не надо столько передавать. Здесь я не писал о spin блокировках, read_write lock, в Win32Api это только в
vista/server2008. Стоит отметить OpenMP но это принадлежит visual studio.

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

Серийный программист
Posix win threads for windows что этоPosix win threads for windows что этоPosix win threads for windows что этоPosix win threads for windows что это

Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 6
Всего: 44

Цитата(0xDX @ 6.3.2009, 04:13)
Стоит отметить OpenMP но это принадлежит visual studio.

ЗЫ для чего вообще это сравнение? что оно дало?

Эксперт
Posix win threads for windows что этоPosix win threads for windows что этоPosix win threads for windows что этоPosix win threads for windows что это

Профиль
Группа: Комодератор
Сообщений: 7036
Регистрация: 28.8.2007
Где: Химки, Московская обл

Репутация: 60
Всего: 223

Так что счет будет явно не в пользу posix.

Серийный программист
Posix win threads for windows что этоPosix win threads for windows что этоPosix win threads for windows что этоPosix win threads for windows что это

Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 6
Всего: 44

xvr, но хоть это не очень хорошо, но всеже все это можно реализовать» используя то что есть.

Эксперт
Posix win threads for windows что этоPosix win threads for windows что этоPosix win threads for windows что этоPosix win threads for windows что это

Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154

Цитата(0xDX @ 6.3.2009, 07:13 Posix win threads for windows что это)
Хотя бы по тому что параметров не надо столько передавать. Здесь я не писал о spin блокировках, read_write lock, в Win32Api это только в
vista/server2008.

Эксперт
Posix win threads for windows что этоPosix win threads for windows что этоPosix win threads for windows что этоPosix win threads for windows что это

Профиль
Группа: Комодератор
Сообщений: 7036
Регистрация: 28.8.2007
Где: Химки, Московская обл

Репутация: 60
Всего: 223

Цитата(chaos @ 6.3.2009, 14:54)
xvr, но хоть это не очень хорошо, но всеже все это можно реализовать» используя то что есть.

Профиль
Группа: Участник
Сообщений: 44
Регистрация: 6.2.2009

Репутация: нет
Всего: нет

Спорный вопрос. Сколько *handle как проверить sizeof()? сколько я памяти использую?

Цитата
Далее, все серия Interlocked* в Win32API инлайнится компилятором, никаких dll не нужно (конечно, если программист не приложит больших усилий, что бы этого не было smile )

и как их сделать инлайн?

Цитата
В posix нет возможности ждать сразу на нескольких разных синхронизирующих примитивах.

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

Эксперт
Posix win threads for windows что этоPosix win threads for windows что этоPosix win threads for windows что этоPosix win threads for windows что это

Профиль
Группа: Комодератор
Сообщений: 7036
Регистрация: 28.8.2007
Где: Химки, Московская обл

Репутация: 60
Всего: 223

Спорный вопрос. Сколько *handle как проверить sizeof()? сколько я памяти использую?

Цитата
Далее, все серия Interlocked* в Win32API инлайнится компилятором, никаких dll не нужно (конечно, если программист не приложит больших усилий, что бы этого не было smile )

Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это Posix win threads for windows что это

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »

[ Время генерации скрипта: 0.1424 ] [ Использовано запросов: 21 ] [ GZIP включён ]

Источник

Видео

Процессы. Способы создания WinAPI и POSIX процессов.

Процессы. Способы создания WinAPI и POSIX процессов.

АКОС. Семинар 23. Многопоточность POSIX Threads

АКОС. Семинар 23. Многопоточность POSIX Threads

Стандарт POSIX

Стандарт POSIX

МНОГОПОТОЧНОСТЬ — C++ WINAPI ЧАСТЬ #10

МНОГОПОТОЧНОСТЬ  -  C++ WINAPI ЧАСТЬ #10

Многопоточность | Потоки | thread | Многопоточное программирование | Уроки | C++ #1

Многопоточность | Потоки | thread | Многопоточное программирование | Уроки | C++ #1

«Опыт 6» с ОС Minix. Создание и взаимодействие процессов: POSIX vs WINAPI

"Опыт 6" с ОС Minix. Создание и взаимодействие процессов: POSIX vs WINAPI

Внимание! Вирус халявщика. Компьютерный вирус! Как удалить вирус?

Внимание! Вирус халявщика. Компьютерный вирус! Как удалить вирус?

mingw-w64 threads: posix vs win32

mingw-w64 threads: posix vs win32

📼 Процессы и потоки (Win32 API).

📼 Процессы и потоки (Win32 API).

Work with Posix thread

Work with Posix thread

Я устанавливаю mingw-w64 на Windows, и есть два варианта: win32 threads и posix threads. Я знаю, в чем разница между потоками win32 и pthreads, но я не понимаю, в чем разница между этими двумя вариантами. Я сомневаюсь, что если я выберу потоки posix, это помешает мне вызывать функции WinAPI, такие как CreateThread.

кажется, что эта опция указывает, какой API потоков будет использоваться некоторой программой или библиотекой, но чем? По НКУ, libstdc++ или что-то еще?

Я нашел это:
в чем разница между thread_posixs и thread_win32 в порту gcc windows?

короче говоря, для этой версии mingw выпуск threads-posix будет использовать API posix и разрешать использование std::thread, а threads-win32 будет использовать API win32 и отключит часть std::thread стандарта.

Ok, если я выберу win32 threads, то std:: thread будет недоступно, но потоки win32 по-прежнему будут использоваться. Но используется кем?

3 ответов


GCC поставляется с библиотекой времени выполнения компилятора (libgcc), которую он использует (среди прочего), обеспечивая низкоуровневую абстракцию ОС для многопоточности связанных функций на языках, которые он поддерживает. Наиболее релевантным примером является libstdc++ ‘ S C++11 <thread>, <mutex> и <future>, которые не имеют полной реализации, когда GCC построен с его внутренней моделью потоков Win32. MinGW-w64 предоставляет winpthreads (реализация pthreads поверх многопоточного API Win32), который Затем GCC может подключиться, чтобы включить все причудливые функции.

Я должен подчеркнуть, что эта опция не запрещает вам писать любой код, который вы хотите (он имеет абсолютно нет влияние на то, какой API вы можете вызвать в своем коде). Он отражает только то, что библиотеки времени выполнения GCC (libgcc / libstdc++/…) использовать для их функциональности. Оговорка, цитируемая @James, не имеет ничего общего с внутренней моделью потоковой передачи GCC, а скорее с реализацией CRT Microsoft.

для подведем итог:

  • posix: включить функции многопоточности C++11/C11. Делает libgcc зависеть от libwinpthreads, так что даже если вы непосредственно не вызываете pthreads API, вы будете распространять WINPTHREADS DLL. Нет ничего плохого в распространении еще одной DLL с вашим приложением.
  • win32: нет функций многопоточности C++11.

ни имеют влияние на любой пользовательский код, вызывающий Win32 APIs или Pthreads APIs. Вы всегда можете использовать оба.


части среды выполнения GCC (в частности, обработка исключений) зависят от используемой модели потоков. Таким образом, если вы используете версию среды выполнения, которая была построена с потоками POSIX, но решили создать потоки в своем собственном коде с API Win32, в какой-то момент у вас могут возникнуть проблемы.

даже если вы используете потоковую версию Win32 среды выполнения, вы, вероятно, не должны вызывать API Win32 напрямую. Цитата из компилятор MinGW FAQ:

поскольку MinGW использует стандартную библиотеку времени выполнения Microsoft C, которая поставляется с Windows, вы должны быть осторожны и использовать правильную функцию для создания нового потока. В частности,CreateThread функция не настроит стек правильно для библиотеки времени выполнения C. Вы должны использовать _beginthreadex вместо этого, который (почти) полностью совместимы с CreateThread.

15

автор: James Holderness


обратите внимание, что теперь можно использовать некоторые из C++11 std::thread в режиме Win32 threading. Эти адаптеры только для заголовков работали из коробки для меня:
https://github.com/meganz/mingw-std-threads

из истории ревизий похоже, что есть какая-то недавняя попытка сделать это частью среды выполнения mingw64.


From Wikipedia, the free encyclopedia

POSIX Threads, commonly known as pthreads, is an execution model that exists independently from a language, as well as a parallel execution model. It allows a program to control multiple different flows of work that overlap in time. Each flow of work is referred to as a thread, and creation and control over these flows is achieved by making calls to the POSIX Threads API. POSIX Threads is an API defined by the standard POSIX.1c, Threads extensions (IEEE Std 1003.1c-1995).

Implementations of the API are available on many Unix-like POSIX-conformant operating systems such as FreeBSD, NetBSD, OpenBSD, Linux, macOS, Android,[1] Solaris, Redox, and AUTOSAR Adaptive, typically bundled as a library libpthread. DR-DOS and Microsoft Windows implementations also exist: within the SFU/SUA subsystem which provides a native implementation of a number of POSIX APIs, and also within third-party packages such as pthreads-w32,[2] which implements pthreads on top of existing Windows API.

Contents[edit]

pthreads defines a set of C programming language types, functions and constants. It is implemented with a pthread.h header and a thread library.

There are around 100 threads procedures, all prefixed pthread_ and they can be categorized into four groups:

  • Thread management — creating, joining threads etc.
  • Mutexes
  • Condition variables
  • Synchronization between threads using read write locks and barriers
  • Spinlocks[3]

The POSIX semaphore API works with POSIX threads but is not part of threads standard, having been defined in the POSIX.1b, Real-time extensions (IEEE Std 1003.1b-1993) standard. Consequently, the semaphore procedures are prefixed by sem_ instead of pthread_.

Example[edit]

An example illustrating the use of pthreads in C:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <pthread.h>
#include <unistd.h>

#define NUM_THREADS 5

void *perform_work(void *arguments){
  int index = *((int *)arguments);
  int sleep_time = 1 + rand() % NUM_THREADS;
  printf("THREAD %d: Started.n", index);
  printf("THREAD %d: Will be sleeping for %d seconds.n", index, sleep_time);
  sleep(sleep_time);
  printf("THREAD %d: Ended.n", index);
  return NULL;
}

int main(void) {
  pthread_t threads[NUM_THREADS];
  int thread_args[NUM_THREADS];
  int i;
  int result_code;
  
  //create all threads one by one
  for (i = 0; i < NUM_THREADS; i++) {
    printf("IN MAIN: Creating thread %d.n", i);
    thread_args[i] = i;
    result_code = pthread_create(&threads[i], NULL, perform_work, &thread_args[i]);
    assert(!result_code);
  }

  printf("IN MAIN: All threads are created.n");

  //wait for each thread to complete
  for (i = 0; i < NUM_THREADS; i++) {
    result_code = pthread_join(threads[i], NULL);
    assert(!result_code);
    printf("IN MAIN: Thread %d has ended.n", i);
  }

  printf("MAIN program has ended.n");
  return 0;
}

This program creates five threads, each executing the function perform_work that prints the unique number of this thread to standard output. If a programmer wanted the threads to communicate with each other, this would require defining a variable outside of the scope of any of the functions, making it a global variable. This program can be compiled using the gcc compiler with the following command:

gcc pthreads_demo.c -pthread -o pthreads_demo

Here is one of the many possible outputs from running this program.

IN MAIN: Creating thread 0.
IN MAIN: Creating thread 1.
IN MAIN: Creating thread 2.
IN MAIN: Creating thread 3.
THREAD 0: Started.
IN MAIN: Creating thread 4.
THREAD 3: Started.
THREAD 2: Started.
THREAD 0: Will be sleeping for 3 seconds.
THREAD 1: Started.
THREAD 1: Will be sleeping for 5 seconds.
THREAD 2: Will be sleeping for 4 seconds.
THREAD 4: Started.
THREAD 4: Will be sleeping for 1 seconds.
IN MAIN: All threads are created.
THREAD 3: Will be sleeping for 4 seconds.
THREAD 4: Ended.
THREAD 0: Ended.
IN MAIN: Thread 0 has ended.
THREAD 2: Ended.
THREAD 3: Ended.
THREAD 1: Ended.
IN MAIN: Thread 1 has ended.
IN MAIN: Thread 2 has ended.
IN MAIN: Thread 3 has ended.
IN MAIN: Thread 4 has ended.
MAIN program has ended.

POSIX Threads for Windows[edit]

Windows does not support the pthreads standard natively, therefore the Pthreads4w project seeks to provide a portable and open-source wrapper implementation. It can also be used to port Unix software (which uses pthreads) with little or no modification to the Windows platform.[4] Pthreads4w version 3.0.0[5] or later, released under the Apache Public License v2.0, is compatible with 64-bit or 32-bit Windows systems. Version 2.11.0,[6] released under the LGPLv3 license, is also 64-bit or 32-bit compatible.

The Mingw-w64 project also contains a wrapper implementation of pthreads, winpthreads, which tries to use more native system calls than the Pthreads4w project.[7]

Interix environment subsystem available in the Windows Services for UNIX/Subsystem for UNIX-based Applications package provides a native port of the pthreads API, i.e. not mapped on Win32 API but built directly on the operating system syscall interface.[8]

See also[edit]

  • Runtime system
  • OpenMP
  • Cilk/Cilk Plus
  • Threading Building Blocks (TBB)
  • Native POSIX Thread Library (NPTL)
  • DCEThreads
  • clone (Linux system call)
  • Spurious wakeup
  • Thread-local storage
  • GNU Portable Threads
  • Grand Central Dispatch (Apple’s thread library)
  • Beginthread (a subroutine within Windows for creating a new thread and unix thread)
  • State Threads, an event driven approach to threading

References[edit]

  1. ^ «libc/bionic/pthread.c — platform/bionic — Git at Google». android.googlesource.com.
  2. ^ «Pthread Win-32: Level of standards conformance». 2006-12-22. Retrieved 2010-08-29.
  3. ^ «pthread.h(0p) — Linux manual page». Retrieved 18 December 2022.
  4. ^ Hart, Johnson M. (2004-11-21). «Experiments with the Open Source Pthreads Library and Some Comments». Archived from the original on 2010-08-30. Retrieved 2010-08-29.
  5. ^ https://sourceforge.net/projects/pthreads4w/files/ — File: pthreads4w-code-v3.0.0.zip — Source for pthreads4w v3.0.0
  6. ^ https://sourceforge.net/projects/pthreads4w/files/ — File: pthreads4w-code-v2.11.0.zip — Source for pthreads4w v2.11.0
  7. ^ see http://locklessinc.com/articles/pthreads_on_windows which is where it was originally derived from
  8. ^ «Chapter 1: Introduction to Windows Services for UNIX 3.5».

Further reading[edit]

  • David R. Butenhof (1997). Programming with POSIX Threads. Addison-Wesley. ISBN 978-0-201-63392-4.
  • Bradford Nichols; Dick Buttlar; Jacqueline Proulx Farell (September 1996). Pthreads Programming. O’Reilly & Associates. ISBN 978-1-56592-115-3.
  • Charles J. Northrup (1996-01-25). Programming with UNIX Threads. John Wiley & Sons. ISBN 978-0-471-13751-1.
  • Kay A. Robbins & Steven Robbins (2003). UNIX Systems Programming. Prentice-Hall. ISBN 978-0-13-042411-2.

External links[edit]

  • The Open Group Base Specifications Issue 7, IEEE Std 1003.1

Понравилась статья? Поделить с друзьями:
  • Poverpoint ru скачать бесплатно для windows 10
  • Posiflex pp 6900 установка windows 10
  • Pov ray for windows что это за программа
  • Posiflex pp 6900 драйвер windows 10
  • Potplayer скачать бесплатно для windows 10 с официального сайта