POSIX Threads — стандарт POSIX-реализации потоков (нитей) выполнения. Стандарт POSIX.1c, Threads extensions (IEEE Std 1003.1c-1995) определяет API для управления потоками, их синхронизации и планирования.

Реализации данного API существуют для большого числа UNIX-подобных ОС (GNU/Linux, Solaris, FreeBSD, OpenBSD, NetBSD, OS X), а также для Microsoft Windows и других ОС.

Библиотеки, реализующие этот стандарт (и функции этого стандарта), обычно называются Pthreads (функции имеют приставку «pthread_»).

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

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

Типы данных: pthread_t: дескриптор потока; pthread_attr_t: перечень атрибутов потока; pthread_barrier_t: барьер; pthread_barrierattr_t: атрибуты барьера; pthread_cond_t: условная переменная; pthread_condattr_t: атрибуты условной переменной; pthread_key_t: данные, специфичные для потока; pthread_mutex_t: мьютекс; pthread_mutexattr_t: атрибуты мьютекса; pthread_rwlock_t: мьютекс с возможностью эксклюзивной блокировки; pthread_rwlockattr_t: атрибуты этого мьютекса; pthread_spinlock_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>

void wait_thread (void); void* thread_func (void*);

int main (int argc, char *argv[], char *envp[]) { pthread_t thread; if (pthread_create(&thread,NULL,thread_func,NULL)) return EXIT_FAILURE; for (unsigned int i = 0; i < 20; i++) { puts("a"); wait_thread();

if (pthread_join(thread,NULL)) return EXIT_FAILURE; return EXIT_SUCCESS; }

void wait_thread (void) { time_t start_time = time(NULL); while(time(NULL) == start_time) {} }

void* thread_func (void* vptr_args) { for (unsigned int i = 0; i < 20; i++) { fputs("b\n",stderr); wait_thread();

return NULL; }

Пример использования потоков на языке C++: #include <cstdlib> #include <iostream> #include <memory> #include <unistd.h> #include <pthread.h>

class Thread { public: int start () { return pthread_create( &_ThreadId, nullptr, Thread::thread_func, this );

int wait () { return pthread_join( _ThreadId, nullptr );

protected: Thread() = default; Thread(const Thread&);

virtual ~Thread () = default; virtual void run () = 0;

static void* thread_func(void* d) { (static_cast <Thread*>(d))->run(); return nullptr;

private: pthread_t _ThreadId;

class TestingThread : public Thread { public: TestingThread (const char* pcszText) : _pcszText( pcszText ) {} virtual void run () { for (unsigned int i = 0; i < 20; i++, usleep(1000)) std::cout << _pcszText << std::endl;

protected: const char* _pcszText;

int main (int argc, char *argv[], char *envp[]) { TestingThread ThreadA("a"); TestingThread ThreadB("b"); return ThreadA.start() || ThreadB.start() || ThreadA.wait() || ThreadB.wait() ? EXIT_FAILURE : EXIT_SUCCESS; }

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

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

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

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

Ссылки Статья «Объясняя потоки POSIX», Даниэля Роббинса (основателя проекта Gentoo) Интервью «10 вопросов Девиду Бутенхофу о параллельном программировании и потоках POSIX» с Майклом Суиссом The Open Group Base Specifications Issue 6, IEEE Std 1003.1 Pthreads Presentation at 2007 OSCON (O’Reilly Open Source Convention) by Adrien Lamothe. An overview of Pthreads with current trends Установка библиотеки pthread.h в среде Visual Studio

Категория:Стандарты POSIX Категория:Потоки выполнения Категория:Статьи с примерами кода Си Категория:Статьи с примерами кода C++ Категория:Библиотеки параллельного программирования Категория:C POSIX library