Потоки POSIX , обычно называемые pthreads , представляют собой модель выполнения, которая существует независимо от языка, а также модель параллельного выполнения. Это позволяет программе управлять несколькими различными потоками работы, которые перекрываются во времени. Каждый рабочий поток называется потоком , и создание и контроль над этими потоками достигается путем выполнения вызовов POSIX Threads API. POSIX Threads - это API, определенный стандартом POSIX.1c, расширениями потоков ( IEEE Std 1003.1c-1995) .
Реализации API доступны во многих Unix-подобных POSIX-совместимых операционных системах, таких как FreeBSD , NetBSD , OpenBSD , Linux , macOS , Android , [1] Solaris , Redox и AUTOSAR Adaptive, обычно в комплекте в виде библиотеки libpthread . Реализации DR-DOS и Microsoft Windows также существуют: в подсистеме SFU / SUA, которая обеспечивает встроенную реализацию ряда API-интерфейсов POSIX, а также в сторонних пакетах, таких какpthreads-w32 , [2], который реализует потоки pthreads поверх существующего Windows API .
Содержание [ править ]
pthreads определяет набор типов , функций и констант языка программирования C. Он реализован с заголовком и библиотекой потоков .pthread.h
Существует около 100 процедур потоков, все с префиксом, pthread_
и их можно разделить на четыре группы:
- Управление потоками - создание, объединение потоков и т. Д.
- Мьютексы
- Переменные условия
- Синхронизация между потоками с использованием блокировок чтения / записи и барьеров
API семафоров POSIX работает с потоками POSIX, но не является частью стандарта потоков, который был определен в стандарте POSIX.1b, Расширения реального времени (IEEE Std 1003.1b-1993) . Следовательно, процедуры семафоров имеют префикс sem_
вместо pthread_
.
Пример [ править ]
Пример, иллюстрирующий использование pthreads в C:
#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <pthread.h>#include <unistd.h>#define NUM_THREADS 5void * perform_work ( void * arguments ) { int index = * (( int * ) arguments ); int sleep_time = 1 + rand () % NUM_THREADS ; printf ( "THREAD% d: Started. \ n " , index ); printf ( "THREAD% d: будет спать% d секунд. \ n " , index , sleep_time ); спать (sleep_time ); printf ( "THREAD% d: Ended. \ n " , index ); }int main ( void ) { потоки pthread_t [ NUM_THREADS ]; int thread_args [ NUM_THREADS ]; int i ; int result_code ; // создаем все потоки один за другим for ( i = 0 ; i < NUM_THREADS ; i ++ ) { printf ( "IN MAIN: Создание потока% d. \ n " , i ); thread_args [ я ] = я ; result_code = pthread_create ( & нити [ я ], NULL , perform_work , и thread_args [ я ]); утверждать (! результат_код ); } printf ( "ГЛАВНАЯ: все потоки созданы. \ n " ); // ждем завершения каждого потока for ( i = 0 ; i < NUM_THREADS ; i ++ ) { result_code = pthread_join ( threads [ i ], NULL ); assert ( ! код_результата ); printf ( "ГЛАВНАЯ: поток% d закончился. \ n " , i ); } printf ( "ГЛАВНАЯ программа завершена. \ n " ); возврат 0 ; }
Эта программа создает пять потоков, каждый из которых выполняет функцию perform_work, которая выводит уникальный номер этого потока на стандартный вывод. Если программист хотел, чтобы потоки взаимодействовали друг с другом, для этого потребовалось бы определить переменную вне области видимости любой из функций, сделав ее глобальной переменной . Эту программу можно скомпилировать с помощью компилятора gcc с помощью следующей команды:
gcc pthreads_demo.c -lpthread -o pthreads_demo
Вот один из многих возможных результатов запуска этой программы.
ГЛАВНАЯ: Создание потока 0.ГЛАВНАЯ: Создание темы 1.ГЛАВНАЯ: Создание потока 2.ГЛАВНАЯ: Создание темы 3.РЕЗЬБА 0: запущена.ГЛАВНАЯ: Создание темы 4.НИТЬ 3: Начато.НИТЬ 2: Начато.НИТЬ 0: будет спать 3 секунды.НИТЬ 1: Начато.НИТЬ 1: будет спать 5 секунд.НИТЬ 2: будет спать 4 секунды.НИТЬ 4: Начато.НИТЬ 4: будет спать в течение 1 секунды.ГЛАВНАЯ: Все темы созданы.НИТЬ 3: будет спать 4 секунды.НИТЬ 4: Закончена.РЕЗЬБА 0: завершена.ГЛАВНАЯ: Тема 0 завершена.НИТЬ 2: Закончена.НИТЬ 3: Закончена.НИТЬ 1: завершена.ГЛАВНАЯ: Тема 1 завершена.ГЛАВНАЯ: Тема 2 закончилась.ГЛАВНАЯ: Тема 3 закончилась.ГЛАВНАЯ: Тема 4 завершена.ГЛАВНАЯ программа закончилась.
POSIX Threads для Windows [ править ]
Windows изначально не поддерживает стандарт pthreads , поэтому проект Pthreads-w32 стремится предоставить переносимую реализацию оболочки с открытым исходным кодом. Его также можно использовать для переноса программного обеспечения Unix (которое использует потоки pthread ) с небольшими изменениями платформы Windows или без них. [3] Последняя версия 2.8.0 с некоторыми дополнительными патчами совместима с 64-битными системами Windows. [4] [5] [6] Версия 2.9.0 также считается 64-битной. [7]
Проект MinGW-w64 также содержит реализацию обертки Pthreads , winpthreads , [8] , который пытается использовать более родные системные вызовы , чем Pthreads-w32 проект. [9]
Подсистема среды Interix, доступная в пакете « Службы Windows для UNIX / Подсистема для приложений на базе UNIX», предоставляет собственный порт API pthreads , то есть не отображаемый на Win32 / Win64 API, а построенный непосредственно на интерфейсе системных вызовов операционной системы . [10]
См. Также [ править ]
- Система выполнения
- OpenMP
- Силк / Силк Плюс
- Строительные блоки с резьбой (TBB)
- Собственная библиотека потоков POSIX (NPTL)
- DCE нити
- clone (системный вызов Linux)
- Ложное пробуждение
- Локальное хранилище потока
- Переносимые потоки GNU
- FSU Pthreads
- Grand Central Dispatch (библиотека потоков Apple)
- Beginthread (подпрограмма в Windows для создания нового потока и потока unix)
- State Threads , управляемый событиями подход к потоковой передаче
Ссылки [ править ]
- ^ "libc / bionic / pthread.c - platform / bionic - Git at Google" . android.googlesource.com .
- ^ «Pthread Win-32: Уровень соответствия стандартам» . 2006-12-22 . Проверено 29 августа 2010 .
- ^ Харт, Джонсон М. (2004-11-21). «Эксперименты с библиотекой Pthreads с открытым исходным кодом и некоторые комментарии» . Архивировано из оригинала на 2010-08-30 . Проверено 29 августа 2010 .
- ^ "pthread-win32_x64.zip Исходные и двоичные файлы для pthreads-w32 v2.8.0" . 2010-01-26 . Проверено 29 августа 2010 .
- ^ «Обсуждение на форуме: pthreads-on-64bit-Windows» . 26 января 2010 г. Архивировано из оригинала на 2010-12-15 . Проверено 29 августа 2010 .
- ^ "Скомпилировать потоки - mingw-w64" . sourceforge.net . Архивировано из оригинала на 2012-07-02 . Проверено 26 июля 2012 .
- ^ http://sourceware.org/pthreads-win32/news.html - упоминается "64 бит"
- ^ mingw-w64 - Версия 5520: / experimental / winpthreads [ постоянная мертвая ссылка ]
- ^ см. http://locklessinc.com/articles/pthreads_on_windows, откуда он был первоначально получен
- ^ «Глава 1: Введение в службы Windows для UNIX 3.5» .
Дальнейшее чтение [ править ]
- Дэвид Р. Бутенхоф (1997). Программирование с использованием потоков POSIX . Эддисон-Уэсли. ISBN 978-0-201-63392-4.
- Брэдфорд Николс; Дик Батлар; Жаклин Пру Фарелл (сентябрь 1996 г.). Программирование потоков . O'Reilly & Associates. ISBN 978-1-56592-115-3.
- Чарльз Дж. Нортрап (1996-01-25). Программирование с помощью потоков UNIX . Джон Вили и сыновья. ISBN 978-0-471-13751-1.
- Кей А. Роббинс и Стивен Роббинс (2003). Системное программирование UNIX . Прентис-Холл. ISBN 978-0-13-042411-2.
Внешние ссылки [ править ]
- Базовые спецификации Open Group, выпуск 7, IEEE Std 1003.1