回答編集履歴

1

コード、実行結果追加

2016/12/23 11:35

投稿

naomi3
naomi3

スコア1105

test CHANGED
@@ -3,3 +3,457 @@
3
3
 
4
4
 
5
5
  よってマルチスレッドプログラミングでは、スケジューリングに依存しない書き方が必要で、どうしても実行順序を決めたいときはセマフォなど「同期オブジェクト」を用いてスレッド同士の「待ち合わせ」を行うことが通例です。
6
+
7
+
8
+
9
+ 追加
10
+
11
+
12
+
13
+ セマフォ2つを使った同期を示します。
14
+
15
+ そこそこまともに動きます。
16
+
17
+ ```C
18
+
19
+ #include <stdio.h>
20
+
21
+ #include <time.h>
22
+
23
+ #include <stdlib.h>
24
+
25
+ #include <string.h>
26
+
27
+ #include <pthread.h>
28
+
29
+ #include <semaphore.h>
30
+
31
+
32
+
33
+ struct ThreadArgs
34
+
35
+ {
36
+
37
+ int *count_num;
38
+
39
+ int *n;
40
+
41
+ int *sum;
42
+
43
+ int thread_id;
44
+
45
+ sem_t* sem4n;
46
+
47
+ sem_t* sem4sum;
48
+
49
+ };
50
+
51
+
52
+
53
+ void *thread_func(void *threadArgs);
54
+
55
+
56
+
57
+ void *thread_func(void *threadArgs) {
58
+
59
+ int i, thread_id;
60
+
61
+ int *n, *count_num, *sum;
62
+
63
+ sem_t* sem4n;
64
+
65
+ sem_t* sem4sum;
66
+
67
+
68
+
69
+ pthread_detach(pthread_self());
70
+
71
+
72
+
73
+ struct ThreadArgs *args = (struct ThreadArgs *) threadArgs;
74
+
75
+
76
+
77
+ n = args -> n;
78
+
79
+ sum = args -> sum;
80
+
81
+ count_num = args -> count_num;
82
+
83
+ thread_id = args -> thread_id;
84
+
85
+ sem4n = args -> sem4n;
86
+
87
+ sem4sum = args -> sem4sum;
88
+
89
+
90
+
91
+ free(threadArgs);
92
+
93
+
94
+
95
+ while ( *sum < *count_num) {
96
+
97
+ (*n)++;
98
+
99
+ printf("Thread%d %d\n", thread_id, *n);
100
+
101
+
102
+
103
+ /* 共有データ*nを使用したので、セマフォの加算 */
104
+
105
+ sem_post(sem4n);
106
+
107
+
108
+
109
+ for (i = 0; i < 50000000; i++) {}
110
+
111
+
112
+
113
+ /* 共有データ*sum, *count_numが使えるようになるまで、セマフォの値によるブロック */
114
+
115
+ sem_wait(sem4sum);
116
+
117
+ }
118
+
119
+ }
120
+
121
+
122
+
123
+ int main(int argc, char *argv[])
124
+
125
+ {
126
+
127
+ int i, j, *n, *top, count_num, thread_num, sum;
128
+
129
+ clock_t time1, time0;
130
+
131
+ double diff;
132
+
133
+ struct ThreadArgs *threadArgs;
134
+
135
+ pthread_t mythread;
136
+
137
+ int thread_id;
138
+
139
+ static sem_t sem4n;
140
+
141
+ static sem_t sem4sum;
142
+
143
+
144
+
145
+ if (argc != 3) {
146
+
147
+ exit(1);
148
+
149
+ }
150
+
151
+
152
+
153
+ count_num = atoi(argv[1]);
154
+
155
+ thread_num = atoi(argv[2]);
156
+
157
+
158
+
159
+ printf("begin %d %d\n", count_num, thread_num);
160
+
161
+
162
+
163
+ n = (int *)malloc(sizeof(int) * thread_num);
164
+
165
+
166
+
167
+ /* セマフォの初期化 */
168
+
169
+ if (sem_init( &sem4n, 0, 0) != 0) {
170
+
171
+ fprintf(stderr, "sem_init() failed\n");
172
+
173
+ exit(1);
174
+
175
+ }
176
+
177
+ if (sem_init( &sem4sum, 0, 0) != 0) {
178
+
179
+ fprintf(stderr, "sem_init() failed\n");
180
+
181
+ exit(1);
182
+
183
+ }
184
+
185
+
186
+
187
+ top = n;
188
+
189
+
190
+
191
+ for (i = 0, n = top; i < thread_num; i++, n++) {
192
+
193
+ *n = 0;
194
+
195
+ }
196
+
197
+
198
+
199
+ sum = 0;
200
+
201
+
202
+
203
+ time0 = clock();
204
+
205
+
206
+
207
+ thread_id = 0;
208
+
209
+
210
+
211
+ for (i = 0, n = top; i < thread_num; i++, n++) {
212
+
213
+ if((threadArgs = (struct ThreadArgs *)malloc(sizeof(struct ThreadArgs))) == NULL){
214
+
215
+ fprintf(stderr, "malloc failed?n"), exit(1);
216
+
217
+ }
218
+
219
+
220
+
221
+ threadArgs -> count_num = &count_num;
222
+
223
+ threadArgs -> n = n;
224
+
225
+ threadArgs -> sum = &sum;
226
+
227
+ threadArgs -> thread_id = thread_id;
228
+
229
+ threadArgs -> sem4n = &sem4n;
230
+
231
+ threadArgs -> sem4sum = &sem4sum;
232
+
233
+
234
+
235
+ if(pthread_create(&mythread, NULL, thread_func, (void *) threadArgs) != 0){
236
+
237
+ fprintf(stderr, "pthread_create() failed\n"), exit(1);
238
+
239
+ }
240
+
241
+
242
+
243
+ thread_id++;
244
+
245
+ }
246
+
247
+
248
+
249
+ while (sum < count_num) {
250
+
251
+ for (i = 0, sum = 0, n = top; i < thread_num; i++, n++) {
252
+
253
+ /* 共有データ*nが使えるようになるまで、セマフォの値によるブロック */
254
+
255
+ sem_wait(&sem4n);
256
+
257
+ sum += *n;
258
+
259
+
260
+
261
+ /* 共有データsum, count_numを使用したので、セマフォの加算 */
262
+
263
+ sem_post(&sem4sum);
264
+
265
+ }
266
+
267
+ //printf("%d %d\n", sum, count_num);
268
+
269
+ }
270
+
271
+
272
+
273
+ /* セマフォの削除 */
274
+
275
+ sem_destroy(&sem4n);
276
+
277
+ sem_destroy(&sem4sum);
278
+
279
+
280
+
281
+ printf("sum %d\n", sum);
282
+
283
+
284
+
285
+ time1 = clock();
286
+
287
+
288
+
289
+ diff =(double)(time1 - time0) / CLOCKS_PER_SEC;
290
+
291
+
292
+
293
+ printf("%.3f[sec]\n", diff);
294
+
295
+
296
+
297
+ return 0;
298
+
299
+ }
300
+
301
+ ```
302
+
303
+ > begin 1000 20
304
+
305
+ Thread0 1
306
+
307
+ Thread1 1
308
+
309
+ Thread2 1
310
+
311
+ Thread3 1
312
+
313
+ Thread4 1
314
+
315
+ Thread5 1
316
+
317
+ Thread6 1
318
+
319
+ Thread7 1
320
+
321
+ Thread8 1
322
+
323
+ Thread9 1
324
+
325
+ Thread10 1
326
+
327
+ Thread11 1
328
+
329
+ Thread12 1
330
+
331
+ Thread13 1
332
+
333
+ Thread14 1
334
+
335
+ Thread15 1
336
+
337
+ Thread16 1
338
+
339
+ Thread17 1
340
+
341
+ Thread18 1
342
+
343
+ Thread19 1
344
+
345
+ Thread0 2
346
+
347
+ Thread2 2
348
+
349
+ Thread5 2
350
+
351
+ Thread1 2
352
+
353
+ Thread3 2
354
+
355
+ Thread6 2
356
+
357
+ Thread4 2
358
+
359
+ Thread7 2
360
+
361
+ Thread9 2
362
+
363
+ Thread8 2
364
+
365
+ Thread10 2
366
+
367
+ Thread11 2
368
+
369
+ Thread12 2
370
+
371
+ Thread14 2
372
+
373
+ Thread13 2
374
+
375
+ Thread15 2
376
+
377
+ Thread16 2
378
+
379
+ Thread17 2
380
+
381
+ Thread18 2
382
+
383
+ Thread2 3
384
+
385
+ Thread6 3
386
+
387
+ Thread10 3
388
+
389
+ Thread5 3
390
+
391
+ Thread0 3
392
+
393
+ ===中略===
394
+
395
+ Thread5 61
396
+
397
+ Thread1 61
398
+
399
+ Thread9 61
400
+
401
+ Thread17 40
402
+
403
+ Thread13 61
404
+
405
+ Thread0 52
406
+
407
+ Thread4 52
408
+
409
+ Thread8 52
410
+
411
+ Thread12 52
412
+
413
+ Thread2 54
414
+
415
+ Thread16 52
416
+
417
+ Thread18 51
418
+
419
+ Thread6 54
420
+
421
+ Thread5 62
422
+
423
+ Thread10 54
424
+
425
+ Thread1 62
426
+
427
+ Thread14 54
428
+
429
+ Thread9 62
430
+
431
+ Thread13 62
432
+
433
+ Thread19 40
434
+
435
+ Thread0 53
436
+
437
+ Thread3 41
438
+
439
+ Thread4 53
440
+
441
+ Thread7 41
442
+
443
+ Thread8 53
444
+
445
+ sum 1010
446
+
447
+ 128.482[sec]
448
+
449
+
450
+
451
+ 環境
452
+
453
+ Windows 7 Professional SP1
454
+
455
+ Intel Core i5 750
456
+
457
+ Cygwin64
458
+
459
+ GCC 5.4.0