前回の記事では、
マルチスレッドプログラミングを
ご紹介しました。
前回のは、最後にリンク貼っておくので、
そっちを先に読むと理解しやすいかも。
今回はMutexを使うことで、
スレッド間で共有する変数に
排他制御を施していきます。
排他制御にはセマフォなど、
有名なものが他にもありますが、
今回は「Mutex」を使います。
「ここで他のスレッドに処理が、
切り替わってはいけない!!」
というパートを保護するものです。
(クリティカルセクションと呼ぶ)
しかしクリティカルセクションは、
プログラマーが決めるので、
コンピュータにも分かるように、
ソース上で明示する必要があります。
処理がクリティカルセクションに
入るときに「ロック」を宣言し、
出るときに「アンロック」を宣言します。
そして、「どこからどこまでを
クリティカルセクションとするか」
によって処理の整合性が変わります。
スレッド間で共通変数を、
書き込む箇所がそれに該当します。
それでは、前回の例をもとに、
Mutexを使って書き換えてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#include<stdio.h> #include<stdlib.h> #include<pthread.h> int sum; pthread_mutex_t using; void *functionSum(void *arg){ int *y = (int*)arg; int x = 1; pthread_mutex_lock(&using); sum = 0; while(x<=*y){ sum += x; x++; } printf("Sum from 1 to %d is %d\n", *y, sum); pthread_mutex_unlock(&using); return NULL; } int main(void){ pthread_t thread1, thread2; int n1, n2; int y; pthread_mutex_init(&using, NULL); n1 = 10000; pthread_create(&thread1, NULL, functionSum, &n1); n2 = 30000; pthread_create(&thread2, NULL, functionSum, &n2); pthread_join(thread1, NULL); pthread_join(thread2, NULL); pthread_mutex_destroy(&using); return 0; } |
ロック or アンロックの状況を
格納するための変数を最初に用意します。
pthread_mutex_t型のmutex用の
変数がpthreadライブラリに用意されています。
クリティカルセクションに入るときに
ロックを宣言します。宣言するときは、
pthread_mutex_lock関数を使います。
1 |
int pthread_mutex_lock(pthread_mutex_t *mutex) |
引数はpthread_mutex_t型の
変数のアドレスを渡します。
これで他のスレッドに邪魔されずに、
処理を進めることが出来ます。
クリティカルセクションを出るときは、
アンロックを宣言する必要があります。
pthread_mutex_unlock関数を使います。
1 |
int pthread_mutex_unlock(pthread_mutex_t *mutex) |
pthread_mutex_lockと同様に、
引数にはpthead_mutex_t型変数の
アドレスを指定します。
pthread_mutex_lockもpthread_mutex_unlockも
成功すれば0を、失敗すれば非ゼロの
エラーコードを戻り値として返します。
またmain文では最初と最後に。
phread_mutex_init関数と
pthread_mutex_destroy関数を
呼び出します。
1 2 |
int pthread_mutex_lock(pthread_mutex_t *mutex) int pthread_mutex_destroy(pthread_mutex_t *mutex) |
プログラムの処理を追っていくと、
実は一方のスレッドが全て和を計算した後に、
残ったスレッドが和を計算します。
今回はシンプルにするために、
和を計算するだけのスレッドを作成しました。
他のスレッドが和を計算してるときは、
終了するのを待たないと共通変数を使えません。
これではスレッドを使わない
プログラムと同じに思えるかもしれません。
しかし終了を待っているときに、
他の処理を進めてあげれば、
スレッドプログラミングの
効果を実感できるかと思います。
最後まで読んでいただきありがとうございました。
前回の記事↓↓↓