###前提
C言語でスレッドの勉強をしています。
練習がてら次のようなプログラムを作成しました。
コマンドライン引数で合計カウント数とスレッド数を入力し実行すると、スレッドごとに0からカウントを始めてすべてのスレッドのカウントの総和が入力した合計カウント数に達すると、プログラムの実行にかかった時間を表示するプログラムです。
標準入出力にスレッド番号とそのスレッドが現在カウントできている値を表示させるようにしています。
スレッド数を増やすと動作がどのように変化するのか、また実行環境を変えると動作が変化するのかを確かめたくてこのようなプログラムを作成してみました。
###発生している問題
プログラム自体はおそらく完成しているのですが、実行環境のせいかMacの標準のターミナル上ではうまく動作するものの、WindowsのCygwinターミナル上ではうまく動作しません。
デバッグしてみたところ、どうやら私のCygwin上ではスレッド数が4を超えると5つめからのスレッドのカウントが私の想像通りには始まっていないことはわかりました。
MacのXcodeに付属するCコンパイラでコンパイルして、ターミナルで実行すると想像通りの動作をしました。
勉強中の拙いソースコードですが、なぜこのようなことが起こるのか教えていただけないでしょうか。
#実行例について
スレッド数4で実行した場合
$./a.out 100 4
begin 100 4
Thread0 1
Thread1 1
Thread2 1
Thread3 1
Thread3 2
Thread1 2
Thread2 2
Thread0 2
Thread1 3
Thread3 3
Thread2 3
Thread0 3
===中略===
Thread3 24
Thread1 24
Thread2 24
Thread0 24
Thread3 25
Thread1 25
Thread0 25
Thread2 25
sum 100
12.109[sec]
スレッド数5で実行した場合
$./a.out 100 5
begin 100 5
Thread0 1
Thread1 1
Thread2 1
Thread3 1
Thread1 2
Thread3 2
Thread0 2
Thread2 2
Thread1 3
Thread3 3
Thread0 3
Thread2 3
===中略===
Thread1 95
Thread3 95
Thread2 96
Thread0 97
Thread1 96
Thread3 96
Thread2 97
Thread0 98
Thread1 97
Thread4 1
Thread3 97
Thread2 98
sum 391
38.390[sec]
###該当のソースコード
C
1#include <stdio.h> 2#include <time.h> 3#include <stdlib.h> 4#include <string.h> 5#include <pthread.h> 6 7static pthread_mutex_t MyMutex=PTHREAD_MUTEX_INITIALIZER; 8 9void *thread_func(void *threadArgs); 10 11struct ThreadArgs 12{ 13 int *count_num; 14 int *n; 15 int *sum; 16 int thread_id; 17}; 18 19void *thread_func(void *threadArgs) { 20 int i, thread_id; 21 int *n, *count_num, *sum; 22 23 pthread_detach(pthread_self()); 24 25 n = ((struct ThreadArgs *) threadArgs) -> n; 26 sum = ((struct ThreadArgs *) threadArgs) -> sum; 27 count_num = ((struct ThreadArgs *) threadArgs) -> count_num; 28 thread_id = ((struct ThreadArgs *) threadArgs) -> thread_id; 29 30 while ( *sum < *count_num) { 31 (*n)++; 32 printf("Thread%d %d\n", thread_id, *n); 33 for (i = 0; i < 50000000; i++) {} 34 } 35 36 free(threadArgs); 37} 38 39int main(int argc, char *argv[]) 40{ 41 int i, j, *n, *top, count_num, thread_num, sum; 42 clock_t time1, time0; 43 double diff; 44 struct ThreadArgs *threadArgs; 45 pthread_t mythread; 46 int thread_id; 47 48 if (argc != 3) { 49 exit(1); 50 } 51 52 count_num = atoi(argv[1]); 53 thread_num = atoi(argv[2]); 54 55 printf("begin %d %d\n", count_num, thread_num); 56 57 n = (int *)malloc(sizeof(int) * thread_num); 58 59 top = n; 60 61 for (i = 0, n = top; i < thread_num; i++, n++) { 62 *n = 0; 63 } 64 65 sum = 0; 66 67 time0 = clock(); 68 69 thread_id = 0; 70 71 for (i = 0, n = top; i < thread_num; i++, n++) { 72 if((threadArgs = (struct ThreadArgs *)malloc(sizeof(struct ThreadArgs))) == NULL){ 73 fprintf(stderr, "malloc failed¥n"), exit(1); 74 } 75 76 threadArgs -> count_num = &count_num; 77 threadArgs -> n = n; 78 threadArgs -> sum = ∑ 79 threadArgs -> thread_id = thread_id; 80 81 if(pthread_create(&mythread, NULL, thread_func, (void *) threadArgs) != 0){ 82 fprintf(stderr, "pthread_create() failed¥n"), exit(1); 83 } 84 85 thread_id++; 86 } 87 88 while (sum < count_num) { 89 pthread_mutex_lock(&MyMutex); 90 for (i = 0, sum = 0, n = top; i < thread_num; i++, n++) { 91 sum += *n; 92 } 93 pthread_mutex_unlock(&MyMutex); 94 //printf("%d %d\n", sum, count_num); 95 } 96 printf("sum %d\n", sum); 97 98 time1 = clock(); 99 100 diff =(double)(time1 - time0) / CLOCKS_PER_SEC; 101 102 printf("%.3f[sec]\n", diff); 103 104 free(top); 105 106 return 0; 107} 108 109
##追加の質問内容
なぜスレッド数5の実行例では、Thread 4(5つめのスレッド)がすぐに開始されないのでしょうか。
##追記
排他処理を追加しました。
追加の質問内容と実行例について加筆しました。
###補足情報(言語/FW/ツール等のバージョンなど)
実行環境
Windows10 Home (intel Core i5 4460)
Cygwin (gnupack_devel-13.06-2015.11.08)
GCC 4.9.3
macOS Sierra 10.12.1 (Core2Duo SU9400)
回答3件
あなたの回答
tips
プレビュー