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

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

新規登録して質問してみよう
ただいま回答率
85.35%
排他制御

排他制御とは、特定のファイル・データへのアクセスや更新を制御することです。特にファイルやデータベースへ書き込みを行う際、データの整合性を保つため別のプログラムによる書き込みを一時的に制御することを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1285閲覧

c++: mutexを用いた排他処理につきまして

guriguri

総合スコア34

排他制御

排他制御とは、特定のファイル・データへのアクセスや更新を制御することです。特にファイルやデータベースへ書き込みを行う際、データの整合性を保つため別のプログラムによる書き込みを一時的に制御することを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/03/28 12:45

編集2020/03/28 12:54

質問内容

2つの異なるスレッドから下記コードの client_work(), get_client() をそれぞれ呼び出します.
排他処理を行い busy状態をチェックしているのでそれぞれのスレッドが同じタイミングにclientを扱うことはない
と考えたのですがどうも同じタイミングでclientを扱うことがあるようです。

mutexの扱いを間違っている箇所等ありますでしょうか?

c++

1mutex mtx; 2 3// 1秒毎にclientのbusy状態をチェックしbusyでなければ、busyにしてからdo()を呼び出す. 4void client_work() { 5 thread th([] { 6 unique_lock<mutex> lock(mtx, defer_lock); // 遅延ロック 7 while (1) { 8 mtx.lock(); 9 if (!client->busy) { 10 client->busy = true; 11 mtx.unlock(); 12 client->do(); // 重い処理を行う 13 client->busy = false; 14 } else { 15 mtx.unlock(); 16 } 17 sleep(1); 18 } 19 } 20 th.detach(); // アプリが終わるまでずっと処理継続 21} 22 23// clientがbusyでなくなった時点でclientを返す. (呼び出し側はclientの処理が終わった時点で client->busy = false にする) 24Client *get_client() { 25 while(1) { 26 lock_guard<mutex> lock(mtx); 27 if(!client->busy) { 28 client->busy = true; 29 return client; 30 } 31 } 32} 33

本来、上のようなケースでは condition_variable などが有効だとは思うのですが
このコードは実際に利用しているコードを極力シンプルにしたものでしてwhileにより都度 busy状態の確認が必須となります。

どうぞ宜しくお願いいたします。

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

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

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

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

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

yuki23

2020/03/28 13:51

このコードで問題の現象が発生するのですか?
SHOMI

2020/03/28 14:09

CPUやコンパイラにより実行順序が変更されてclient->do();より先にclient->busy = false;が実行されているのかもしれません。
guriguri

2020/03/28 15:04

yuki23さん  実際のコードをシンプルにしたものですのでこれが動作していないわけではないのですが 実際のコードと排他制御の部分は全く一緒です。 SHOMIさん え、そんなことが・・・?
guriguri

2020/03/28 15:59

yuki23さん、SHOMIさん 本当に申し訳ないのですがシンプルにしたコードが間違っておりました・・・。 実際のコードではlockとunlockが一致しておりませんでした。
guest

回答1

0

自己解決

実際のコードが間違っておりました。
lockとunlockが一致しておりませんでした。
すみません。

投稿2020/03/28 16:00

guriguri

総合スコア34

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問