C言語のマルチスレッドプログラミング

提供: C言語入門
2017年9月3日 (日) 23:08時点におけるDaemon (トーク | 投稿記録)による版

移動: 案内検索
スポンサーリンク

C言語では、スレッドライブラリを用いて、プログラムをマルチスレッド化し、処理を並列化できます。プログラムを並列化することにより、同時にきたリクエストを同時にさばけるようになったり、複数のリソースに対するアクセスを並列化することで、全体の処理時間を短くすることができます。

読み方

マルチスレッドプログラミング
まるちすれっど ぷろぐらみんぐ
multi thread programming
まるちすれっど ぷろぐらみんぐ

概要

C言語のプログラムは、並列ライブラリか、fork などのプロセス生成の仕組みを使わない限り、プログラムは、1つの処理しか同時に実行できません。 シングルプロセスのシングルスレッドなプログラムは、同時に1つのことしかできません。そのため、シングルプロセスのウェブサーバは、同時に1つのブラウザのリクエストしか処理できません。複数のデータベースからデータを読まなければならないプログラムは、1つ1つのデータベースに順番に問い合わせしなければなりません。1つのデータベースに投げるクエリが30分かかる場合、3つのデータベースに問い合わせをしたら、合計で90分も時間が掛かってしまいます。

プログラムは、並列化を行うことで、処理を同時に行い、全体の処理時間を短くすることができます。プログラムのマルチスレッド化(並列化)は、スレッドライブラリを用いて実現します。並列化することにより、ウェブサーバは同時にクライアントのリクエストに応えることができるようになります。複数のデータベースの問い合わせを同時に行うことができ、一番ながくかかる問い合わせの時間が、プログラムの実行時間になります。並列化により、さまざまなメリットがあります。

プログラムの並列化のメリット

プログラムを並列化(マルチスレッド)にするメリットは、処理を同時にできるということです。

3つの WebAPI を呼び出すプログラムを書く場合に、1つ1つの WebAPI の呼び出しをシーケンシャル(順番に行う)行う場合と、同時に接続する場合を考えてみましょう。

直列に1つ1つ呼び出す場合には、1つの WebAPI が完了するまで、次の API を呼び出すことができません。1APIのリクエストが1秒かかる場合、同型で3秒かかります。

3つの WebAPI を同時に呼び出したらどうでしょうか? 1秒掛かる WebAPI を同時に 3つ呼び出した場合、合計時間は、1秒になります。

並列化すれば、処理に必要なメモリの量が増えたり、同時に通信すれば、通信の割込がその分増えたりといったことも発生します。一方で、全体の処理時間を減らせる場合もあります。

プログラムの並列化の実現方法

プログラムの並列化の実現方法は、以下の通りです。

  • マルチスレッドを利用する
  • マルチプロセス化する

マルチプロセス化は、Unix 系の OS であれば、 fork() システムコールを用いて、プログラムを生成することできます。

マルチスレッド化には、Unix 系 OS であれば、 pthread と呼ばれるライブラリで実現できます。OpenMP などを利用するとプリプロセッサディレクティブ で簡単にプログラムを並列化することもできます。

マルチプロセスとマルチスレッド

マルチプロセスとマルチスレッドは、以下のように異なります。

マルチプロセス(forkモデル)
データを共有する必要がないか、少数のデータを共有する場合は、複数のプロセス(マルチプロセス)を起動し、プロセス間通信や共有メモリを用いて、データを共有するモデルです。
マルチスレッド
メモリ空間を共有し、複数のスレッドでデータを共有するモデルです。

マルチプロセスモデル(forkモデル)では、メモリ空間がプロセスごとに異なります。そのため、データの共有は、プロセス間通信を用いるか、共有メモリ(シェアードメモリ)を用いて、実現します。プロセス間通信には、名前付きパイプやUnixドメインソケット, ソケットなどを用いることができます。マルチプロセスモデルは、プロセスが独立しているため、プログラムがクラッシュしても、影響範囲をクラッシュしたプロセスに限定できるメリットがあります。 fork()自体に時間がかかり、プロセスが生成されるため、メモリを消費するというデメリットもあります。

マルチスレッドモデルは、1つのプロセス内に複数のスレッドを持ちます。スレッドは同じメモリ空間で実行されます。1つのプロセスであるため、プログラムがクラッシュした場合、影響は全体に波及します。1プロセスであるため、軽量で、メモリの消費量が少なくて済みます。マルチスレッドプログラムは、一般的にデバッグがしにくい側面があります。マルチスレッドでは、変数へのアクセスは、ロックを必要とします。非効率なロックは、プログラムの効率を悪化させ、スレッド化のメリットをなくしてしまうこともあります。

スレッドを実現する技術

スレッドプログラミングを実現するには、スレッドライブラリを利用するか、並列化のためのキーワードを用います。

以下は、スレッドライブラリです。

以下は、プロプロセッサディレクティブで並列化を簡単に実現できます。

関連項目




スポンサーリンク