質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

878閲覧

C言語 排他制御が正しく行われない原因を知りたいです

Rin2590

総合スコア23

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2022/11/15 10:13

問題

Cによる排他制御の入門の内容です.

スレッド1が sumに「2」を加算.
スレッド2が sumに「3」を加算.

1回の処理でスレッド1,2の合計で「5」を加算できれば良くて,

最終的に sum=50000になれば正解なのですが,30000ほどの結果になってしまいます.

排他制御に精通している方,是非よろしくお願いします!

実現したいこと

・正しく機能しない理由を知りたい
・sum=50000 になるように排他制御を修正したい.

該当のソースコード

#include <stdio.h> #include <stdlib.h> #include <err.h> #include <pthread.h> #include <unistd.h> #include <string.h> #define TRUE 1 #define FALSE 0 const size_t loop_max = 10000; int flag = FALSE; int sum = 0; void f1(); void f2(); int main(int argc, char *argv[]) { pthread_t thread1, thread2; int ret1,ret2; pthread_create(&thread1,NULL,(void *)f1,NULL); pthread_create(&thread2,NULL,(void *)f2,NULL); pthread_join(thread1,NULL); pthread_join(thread2,NULL); printf("done\n"); printf("sum=%d\n", sum); return 0; } void f1() { size_t i; printf("start thread1\n"); for(i=0; i<loop_max; i++){ while(flag){} flag = TRUE; sum += 2; flag = FALSE; } printf("finish thread1\n"); } void f2() { size_t i; printf("start thread2\n"); for(i=0; i<loop_max; i++){ while(flag){} flag = TRUE; sum += 3; flag = FALSE; } printf("finish thread2\n"); }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

Text

1割り込み処理が行われている。

投稿2022/11/15 11:42

atcoderyellow

総合スコア481

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

pthread_mutex 使って排他すればいい。
https://qiita.com/ryo_manba/items/e48faf2ba84f9e5d31c8

C

1#include <stdio.h> 2#include <pthread.h> 3 4const size_t loop_max = 10000; 5 6int sum = 0; 7pthread_mutex_t mtx; 8 9void f1() { 10 size_t i; 11 printf("start thread1\n"); 12 for(i=0; i<loop_max; i++){ 13 pthread_mutex_lock(&mtx); 14 sum += 2; 15 pthread_mutex_unlock(&mtx); 16 } 17 printf("finish thread1\n"); 18} 19 20void f2() { 21 size_t i; 22 printf("start thread2\n"); 23 for(i=0; i<loop_max; i++){ 24 pthread_mutex_lock(&mtx); 25 sum += 3; 26 pthread_mutex_unlock(&mtx); 27 } 28 printf("finish thread2\n"); 29} 30 31int main() { 32 pthread_t thread1, thread2; 33 pthread_mutex_init(&mtx, NULL); 34 35 pthread_create(&thread1,NULL,(void *)f1,NULL); 36 pthread_create(&thread2,NULL,(void *)f2,NULL); 37 38 pthread_join(thread1,NULL); 39 pthread_join(thread2,NULL); 40 41 pthread_mutex_destroy(&mtx); 42 printf("done\n"); 43 printf("sum=%d\n", sum); 44 return 0; 45}

実行結果:

start thread1 start thread2 finish thread1 finish thread2 done sum=50000

投稿2022/11/15 10:41

編集2022/11/15 12:23
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Rin2590

2022/11/15 12:40

解答ありがとうございました! 良い感じで競合を防いでくれて感謝です. 他の皆さんも参考にさせていただきます!
guest

0

while(flag){}

双方のスレッドで同時にこのループを抜けてしまったら排他にはなりませんな

投稿2022/11/15 11:05

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問