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

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

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

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

スコープ

スコープとは、プログラム内で変数名など、参照可能な有効範囲のことを指します。

C++

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

Q&A

解決済

2回答

1588閲覧

子関数の排他について

tyapapa

総合スコア51

排他制御

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

スコープ

スコープとは、プログラム内で変数名など、参照可能な有効範囲のことを指します。

C++

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

0グッド

0クリップ

投稿2020/05/14 03:38

C++

1std::mutex mtx; 2 3sample(void); 4{ 5 6 std::lock_guard<std::mutex> lock(mtx); 7 8 int a; 9 int b; 10 example(a, b); 11} 12 13example(int a, int b) 14{ 15 int c; 16 example_2(c); 17} 18 19example_3(int c) 20{ 21 省略 22}

上記のようなソースがあるとします。
std::lock_guardstd::mutexはスコープ単位で排他をかけてくれる認識ですが
この場合example3にアクセスしている場合も他のスレッドから操作ができないようにロックはかかっているのでしょうか?

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

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

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

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

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

fana

2020/05/14 05:05

何と言うか,もうちょっと質問を整理した方が良いのでは. どういう呼び出し方に関する話を想定しているのか,とか. あと,ソースも間違いと思わしき点が見られるし.
guest

回答2

0

ベストアンサー

以下のようなコードで試してみたら、example_2のところでデッドロックしたっぽいので、子関数でもロックはかかっていると思います。

C++

1#include <iostream> 2#include <mutex> 3 4std::mutex mtx; 5 6void example_2(int c) 7{ 8 std::lock_guard<std::mutex> lock(mtx); 9 std::cout << "lock2" << std::endl; 10} 11 12void example(int a, int b) 13{ 14 int c = 3; 15 example_2(c); 16} 17 18void sample(void) 19{ 20 std::lock_guard<std::mutex> lock(mtx); 21 std::cout << "lock1" << std::endl; 22 23 int a = 1; 24 int b = 2; 25 example(a, b); 26} 27 28int main() 29{ 30 sample(); 31}

投稿2020/05/14 04:56

hytNInE

総合スコア133

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

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

tyapapa

2020/05/14 05:13

ソース展開ありがとうございます! 私の方でもデバッグしてみたところデッドロックが起こりました。 排他がかかっているようですね。ありがとうございます。
guest

0

明示的に排他しないかぎりno-guardです。

[追記] 説明足りんかったかな。

void f() { なんかする } void g() { ここでガード f(); }

g()が呼ばれたらf()内の"なんかする"の間はガードされています。
が、f()が直接呼ばれたらガードされてません。
なので、利用者は絶対にf()を直接呼ばないならこれでいいけど、
利用者にf()を公開するならf()でもガードせにゃなりません。
ところがf()でガードするとg()から呼ばれたときに多重ロックが発生します。
それを回避するには recursive_mutex を使うことになろうかと。

投稿2020/05/14 03:40

編集2020/05/14 05:53
episteme

総合スコア16614

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

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

tyapapa

2020/05/14 04:54 編集

example_3の関数内でstd::lock_guard<std::mutex> lock(mtx);を宣言して 明示的に排他しないとダメと言うことですか?
episteme

2020/05/14 05:33

もちろんそのexample_3からsample呼んだりすると多重ロックとなります。 多重ロックを回避するには shared_lock を使うことになるかな。
episteme

2020/05/14 05:53

ごめん、shared_lockじゃないや。 回答に[追記]しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問