pthreads
В вычислениях , потоки POSIX , широко известные как pthreads , представляют собой модель выполнения , существующую независимо от языка программирования а также модель параллельного выполнения . Это позволяет программе управлять несколькими различными потоками работы, которые перекрываются во времени. Каждый поток работы называется потоком , а создание и управление этими потоками достигается путем вызовов API потоков POSIX . POSIX Threads — это API, определенный стандартом Института инженеров по электротехнике и электронике (IEEE) 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_
и их можно разделить на четыре группы:
- Управление потоками – создание, присоединение к потокам и т. д.
- Мьютексы
- Условные переменные
- Синхронизация между потоками с использованием блокировок чтения и записи и барьеров.
- Спинлоки [3]
POSIX API семафоров работает с потоками 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 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;
}
Эта программа создает пять потоков, каждый из которых выполняет функцию Perform_work , которая выводит уникальный номер этого потока в стандартный вывод. Если бы программист хотел, чтобы потоки взаимодействовали друг с другом, для этого потребовалось бы определить переменную вне области действия любой из функций, сделав ее глобальной переменной . Эту программу можно скомпилировать с помощью компилятора gcc следующей командой:
gcc pthreads_demo.c -pthread -o pthreads_demo
Вот один из многих возможных результатов запуска этой программы.
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-потоки для Windows
[ редактировать ]Windows не поддерживает стандарт pthreads изначально, поэтому проект Pthreads4w стремится предоставить переносимую реализацию оболочки с открытым исходным кодом. Его также можно использовать для переноса программного обеспечения Unix (которое использует pthreads) с небольшими изменениями или без них на платформе Windows. [4] Pthreads4w версия 3.0.0 [5] или более поздняя версия, выпущенная под лицензией Apache Public License v2.0, совместима с 64-битными или 32-битными системами Windows. Версия 2.11.0, [6] выпущенный по лицензии LGPLv3, также совместим с 64-битными или 32-битными версиями.
Проект Mingw-w64 также содержит реализацию оболочки pthreads, winpthreads , которая пытается использовать больше собственных системных вызовов, чем проект Pthreads4w. [7]
Подсистема среды Interix, доступная в пакете Службы Windows для UNIX/Подсистема для приложений на базе UNIX, предоставляет собственный порт API pthreads, т.е. не сопоставленный с Win32 API, а встроенный непосредственно в интерфейс системных вызовов операционной системы . [8]
См. также
[ редактировать ]- Система выполнения
- OpenMP
- Силк / Силк Плюс
- Строительные блоки резьбы (TBB)
- Собственная библиотека потоков POSIX (NPTL)
- DCEThreads
- клонировать (системный вызов Linux)
- Ложное пробуждение
- Локальное хранилище потока
- Переносимые потоки GNU
- Grand Central Dispatch (библиотека потоков Apple)
- Beginthread (подпрограмма в Windows для создания нового потока и потока Unix)
- State Threads — подход к многопоточности, управляемый событиями.
Ссылки
[ редактировать ]- ^ «libc/bionic/pthread.c — платформа/bionic — Git в Google» . android.googlesource.com .
- ^ «Pthread Win-32: Уровень соответствия стандартам» . 22 декабря 2006 г. Архивировано из оригинала 11 июня 2010 г. Проверено 29 августа 2010 г.
- ^ «pthread.h(0p) — страница руководства Linux» . Проверено 18 декабря 2022 г.
- ^ Харт, Джонсон М. (21 ноября 2004 г.). «Эксперименты с библиотекой Pthreads с открытым исходным кодом и некоторые комментарии» . Архивировано из оригинала 30 августа 2010 г. Проверено 29 августа 2010 г.
- ^ Файл: pthreads4w-code-v3.0.0.zip — источник для pthreads4w v3.0.0.
- ^ Файл: pthreads4w-code-v2.11.0.zip — Источник pthreads4w v2.11.0.
- ^ см. http://locklessinc.com/articles/pthreads_on_windows , откуда он был первоначально получен.
- ^ «Глава 1: Введение в службы Windows для UNIX 3.5» . 5 декабря 2007 г.
Дальнейшее чтение
[ редактировать ]- Дэвид Р. Бутенхоф (1997). Программирование с использованием потоков POSIX . Аддисон-Уэсли. ISBN 978-0-201-63392-4 .
- Брэдфорд Николс; Дик Баттлар; Жаклин Пру Фарелл (сентябрь 1996 г.). Программирование Pthreads . О'Рейли и партнеры. ISBN 978-1-56592-115-3 .
- Чарльз Дж. Нортруп (25 января 1996 г.). Программирование с использованием потоков UNIX . Джон Уайли и сыновья. ISBN 978-0-471-13751-1 .
- Кей А. Роббинс и Стивен Роббинс (2003). UNIX-системное программирование . Прентис-Холл. ISBN 978-0-13-042411-2 .