Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

POSIXスレッドライブラリ(Pthreads)とは?基本APIとマルチスレッドのサンプルコード

Pthreads(POSIXスレッド)とは

Pthreadsとは、スレッドの作成と同期のためのAPIを定義したPOSIX標準規格(IEEE 1003.1c)のことです。重要なのは、Pthreadsが定義しているのはスレッドの動作仕様であって、具体的な実装ではないという点です。このため、OS設計者はこの仕様をどのような方法でも自由に実装できます。

実際に多くのOSがPthreads仕様を採用しており、そのほとんどはLinux、macOS(旧Mac OS X)、SolarisといったUNIX系システムです。WindowsはPthreadsをネイティブにはサポートしていませんが、サードパーティ製の実装を利用することで使用可能です。

マルチスレッドプログラムの例

以下のCプログラムは、別スレッドで非負整数の総和を計算するマルチスレッドプログラムを構築するための、基本的なPthreads APIの使い方を示したものです。

Pthreadsプログラムでは、各スレッドは指定された関数から実行を開始します。以下のプログラムでは、その役割を担うのがrunner()関数です。プログラム起動時にはmain()関数内で単一の制御スレッドが開始されます。続いていくつかの初期化処理を行った後、main()が2つ目のスレッドを生成し、新しいスレッドはrunner()関数から制御を開始します。そして両方のスレッドは、グローバル変数sumを共有します。

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

int sum; /* 変数sumは複数のスレッド間で共有される */

/* 各スレッドが呼び出す関数 */
void *runner(void *param);

int main(int argc, char *argv[])
{
    pthread_t tid;       /* スレッド識別子 */
    pthread_attr_t attr; /* スレッド属性の集合 */

    if (argc != 2) {
        fprintf(stderr, "usage: a.out <integer value>\n");
        return -1;
    }
    if (atoi(argv[1]) < 0) {
        fprintf(stderr, "%d must be >= 0\n", atoi(argv[1]));
        return -1;
    }

    /* デフォルトの属性を取得する */
    pthread_attr_init(&attr);
    /* スレッドを生成する */
    pthread_create(&tid, &attr, runner, argv[1]);
    /* スレッドの終了を待機する */
    pthread_join(tid, NULL);

    printf("sum = %d\n", sum);
}

/* スレッドはここから制御を開始する */
void *runner(void *param)
{
    int i, upper = atoi(param);
    sum = 0;

    for (i = 1; i <= upper; i++)
        sum += i;

    pthread_exit(0);
}

▲ Pthreads APIを使用したマルチスレッドCプログラム

プログラムのポイント

  • pthread_create():新しいスレッドを生成し、指定した関数(ここではrunner())から実行を開始させます。引数として、スレッドID、スレッド属性、実行する関数、関数へ渡すパラメータを指定します。
  • pthread_join():指定したスレッドの終了を親スレッドが待機するための関数です。これにより、計算結果の出力前にmain()が終了してしまう事態を防ぎます。
  • データの共有:グローバル変数sumは両方のスレッドからアクセスできます。ワーカースレッドが計算した結果をmain()側で出力できるのは、このデータ共有によるものです。
  • エラー処理:コマンドライン引数の個数チェックや負の値の検出など、入力値の妥当性確認もmain()内で行っています。
  1. C#でスレッドを強制終了する方法|フラグ変数を使った安全な終了手法

    C#で実行中のスレッドを終了させたい場合、かつては Thread.Abort() メソッドが使われていましたが、現在は非推奨となっています(.NET Core 以降ではサポートされていません)。代わりに、bool型のフラグ変数を活用して、スレッドの処理を安全に停止させる方法が一般的です。 この記事では、フラグ変数と Thread.Join() を組み合わせて、実行中のスレッドを確実に終了させる方法をサンプルコード付きで解説します。 1. スレッドを作成して開始する まず、新しいスレッドを作成し、開始します。 // 新しいスレッドを作成 Thread thread = new Thread(c.

  2. Javaのスレッドプールとは?仕組みと実装例をわかりやすく解説

    スレッドプールとはスレッドプール(Thread Pool)とは、あらかじめ初期化された複数のスレッドをまとめて管理する仕組みのことです。基本的な考え方は、アプリケーションの起動時に一定数のスレッドを作成してプールに入れておき、それらのスレッドが仕事を待機するというものです。サーバーがリクエストを受け取ると、利用可能なスレッドがあればプールから1つ取り出して処理を任せます。スレッドはタスクの完了後、破棄されることなくプールへ戻り、次の仕事を待ちます。もしプール内に空きスレッドが存在しない場合は、空きができるまでサーバー側で待機することになります。スレッドプールのメリットタスクごとに新しいスレッド