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

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

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

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

Q&A

解決済

1回答

501閲覧

プロセス間の排他処理

taksr

総合スコア1

C

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

0グッド

0クリップ

投稿2023/10/04 12:02

実現したいこと

2つの子プロセス間でセマフォを使用して変数cntを10にしたいです。

前提

fork, sem_open, sem_wait, sem_post, sem_close, sem_unlinkを使用して、子プロセス間での排他処理を行いたいのですが、上手くいかないのでアドバイスをいただきたいです。
下記のコードだと各子プロセスでcntがインクリメントされてしまい、変数の共有が出来ていない状況です。スレッドではなくプロセスを使用したいのですが、やはり記憶領域を共有するスレッドでないと排他処理は出来ないのでしょうか?

発生している問題・エラーメッセージ

cnt 1 cnt 2 cnt 3 cnt 4 cnt 5 cnt 1 cnt 2 cnt 3 cnt 4 cnt 5

該当のソースコード

C

1# include <stdio.h> 2# include <string.h> 3# include <stdlib.h> 4# include <unistd.h> 5# include <pthread.h> 6# include <stdbool.h> 7# include <semaphore.h> 8# include <sys/time.h> 9# include <sys/types.h> 10# include <sys/stat.h> 11# include <sys/wait.h> 12# include <fcntl.h> 13# include <signal.h> 14 15void func(sem_t *sem, int *cnt) 16{ 17 int i = 0; 18 sem_wait(sem); 19 while(i < 5) 20 { 21 (*cnt)++; 22 i++; 23 printf("cnt %d\n",*cnt); 24 } 25 sem_post(sem); 26 exit(0); 27} 28 29int main() 30{ 31 pid_t pid; 32 pid_t pid2; 33 sem_t *sem; 34 int *status; 35 int cnt; 36 37 cnt = 0; 38 sem_unlink("hello"); 39 sem = sem_open("hello", O_CREAT, 0644, 1); 40 pid = fork(); 41 if(pid == 0) 42 func(sem, &cnt); 43 pid2 = fork(); 44 if(pid2 == 0) 45 func(sem, &cnt); 46 waitpid(pid, status, 0); 47 waitpid(pid2, status, 0); 48 sem_close(sem); 49 return(0); 50}

試したこと

sem_waitをwhileの直後にすると、デッドロックになってしまうのか、cnt 1を出力後に止まってしまいます。

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

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

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

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

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

guest

回答1

0

ベストアンサー

変数cntは、メモリ上の物なので当然ながらプロセスごとに別物です。
複数プロセスで、同じ物を更新したければ、ファイルか、共有メモリー上にcnt相当を置きましょう。

排他処理そのものは出来ているのではないかと思います。

投稿2023/10/04 12:56

otn

総合スコア86281

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

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

taksr

2023/10/04 13:38

ご回答ありがとうございます。共有メモリ上というのは、shmgetやshmget等を使用するということでしょうか。
otn

2023/10/04 14:15

そうですね。 そういうのを使うのが面倒くさいが、ディスクIOを回避したい場合は、メモリ上のファイル( df コマンドで tmpfs と表示される場所)を使うのが楽です。 ・インストール時の設定次第ですが、わりと多くのLinux機では /tmp が tmpfs(手元の環境は違うが) ・/dev/shm は必ずあるはず。ただしシステムで使うので、ファイルの名前が衝突しないように。名前付きセマフォー自体のファイルもここに作られるはず ・「/run/user/ユーザIDの数字」というディレクトリがあればここは自由に使えるはず メモリー上とは言え、ope/close/read/writeのシステムコール経由でアクセスするので、shmgetしたメモリーにポインタ経由でアクセスするのよりは有意に遅いと思いますが。
taksr

2023/10/04 16:17

勉強になります!!ありがとうございます🙏
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問