コンピューティングにおいて、POSIX スレッド(一般的にはヘッダーファイル<pthread.h>にちなんでpthreadsと呼ばれる)は、プログラミング言語とは独立して存在する実行モデルであり、並列実行モデルでもあります。これにより、プログラムは時間的に重なり合う複数の異なる作業フローを制御できます。各作業フローはスレッドと呼ばれ、これらのフローの作成と制御は POSIX スレッドAPIを呼び出すことによって行われます。POSIX スレッドは、IEEE標準POSIX .1c、スレッド拡張 (IEEE Std 1003.1c-1995)で定義されている API です。
API の実装は、 FreeBSD、NetBSD、OpenBSD、Linux、macOS、Android、[ 1 ] Solaris、Redox、QNX、AUTOSAR Adaptiveなど、多くのUnix ライクなPOSIX 準拠オペレーティングシステムで利用可能であり、通常はライブラリlibpthreadとしてバンドルされています。DR -DOSおよびMicrosoft Windows の実装も存在します。これは、多数の POSIX API のネイティブ実装を提供するSFU/SUAサブシステム内、および既存のWindows APIの上に pthreads を実装するpthreads - w32 [ 2 ]などのサードパーティパッケージ内です。
pthreadsは、C言語の型、関数、定数のセットを定義します。pthread.hヘッダーファイルとスレッドライブラリによって実装されています。
スレッド手順は約100種類あり、すべて接頭辞が付いておりpthread_、5つのグループに分類できます。
POSIXセマフォAPI は POSIX スレッドで動作しますが、スレッド標準の一部ではなく、POSIX.1b リアルタイム拡張 (IEEE Std 1003.1b-1993)sem_標準で定義されています。そのため、セマフォ手順には ではなく がプレフィックスとして付けられますpthread_。
C言語におけるpthreadsの使用例を示す。
#include <assert.h> #include <stdio.h> #include <stdlib.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 ( "スレッド %d: 開始しました。\n " , index ); printf ( "スレッド %d: %d 秒間スリープします。\n " , index , sleep_time ); sleep ( sleep_time ); printf ( "スレッド %d: 終了しました。\n " , index ); return NULL ; }int main ( void ) { pthread_t threads [ NUM_THREADS ]; int thread_args [ NUM_THREADS ]; int result_code ; // すべてのスレッドを 1 つずつ作成for ( int 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 ( "main関数内: すべてのスレッドが作成されました。\n " );// 各スレッドの完了を待つfor ( int 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 ( "メインプログラムが終了しました。\n " ); return 0 ; }このプログラムは5つのスレッドを作成し、各スレッドはperform_work関数を実行して、そのスレッドの一意の番号を標準出力に出力します。プログラマがスレッド同士で通信させたい場合は、いずれの関数のスコープ外にも変数を定義し、それをグローバル変数にする必要があります。このプログラムは、 gccコンパイラを使用して次のコマンドでコンパイルできます。
gcc pthreads_demo.c -pthread -o pthreads_demo
これは、このプログラムを実行した際に発生する可能性のある多くの出力のうちの1つです。
main: スレッド 0 を作成しています。main: スレッド1 を作成しています。main: スレッド 2 を作成しています。 main: スレッド 3 を作成しています。 スレッド 0: 開始しました。main: スレッド4 を作成しています。 スレッド 3: 開始しました。スレッド 2:開始しました。 スレッド 0: 3 秒間スリープします。 スレッド 1:開始しました。スレッド 1: 5 秒間スリープします。スレッド 2: 4 秒間スリープします。スレッド 4: 開始しました。 スレッド 4: 1 秒間スリープします。main: すべてのスレッドが作成されました。スレッド 3: 4 秒間スリープします。スレッド 4: 終了しました。スレッド 0: 終了しました。main: スレッド 0 が終了しました。 スレッド 2: 終了しました。スレッド 3: 終了しました。 スレッド 1: 終了しました。main: スレッド 1 が終了しました。main: スレッド 2 が終了しました。main: スレッド 3 が終了しました。main: スレッド 4 が終了しました。メインプログラムは終了しました。Windows は pthreads 標準をネイティブにサポートしていないため、Pthreads4w プロジェクトは移植可能でオープンソースのラッパー実装を提供することを目指しています。また、pthreads を使用するUnixソフトウェアを Windows プラットフォームにほとんどまたはまったく変更を加えることなく移植するためにも使用できます。 [ 4 ] Apache Public License v2.0 の下でリリースされたPthreads4w バージョン 3.0.0 [ 5 ]以降は、64 ビットまたは 32 ビットの Windows システムと互換性があります。LGPLv3 ライセンスの下でリリースされたバージョン 2.11.0 [ 6 ]も、64 ビットまたは 32 ビットと互換性があります。
Mingw -w64プロジェクトには、'pthreads'のラッパー実装であるwinpthreadsも含まれており、これはPthreads4wプロジェクトよりも多くのネイティブシステムコールを使用しようとしています。[ 7 ]
Windows Services for UNIX/Subsystem for UNIX-based Applicationsパッケージで利用可能なInterix環境サブシステムは、pthreads API のネイティブ ポートを提供します。つまり、Win32 API にマッピングされるのではなく、オペレーティングシステムのシステムコールインターフェイスに直接構築されています。[ 8 ]