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

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

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

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

解決済

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

Rin2590
Rin2590

総合スコア23

C

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

3回答

0グッド

0クリップ

471閲覧

投稿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"); }

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答3

2

Text

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

投稿2022/11/15 11:42

atcoderyellow

総合スコア481

Hevendor👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

2022/11/16 02:52

こちらの回答が複数のユーザーから「質問に対する回答となっていない投稿」という指摘を受けました。

2022/11/15 15:57

こちらの回答が他のユーザーから「スパムと見受けられる内容を含む回答」という指摘を受けました。

2

ベストアンサー

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

総合スコア16005

Bearded-Ockham👍を押しています
int32_t👏を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Rin2590

2022/11/15 12:40

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

0

while(flag){}

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

投稿2022/11/15 11:05

y_waiwai

総合スコア86013

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C

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