名前空間
変種
操作

std::shared_mutex::lock_shared

From cppreference.com
< cpp‎ | thread‎ | shared mutex
 
 
並行性サポートライブラリ
スレッド
(C++11)
(C++20)
this_thread 名前空間
(C++11)
(C++11)
(C++11)
協調的なキャンセル
排他制御
(C++11)
汎用ロック管理
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
条件変数
(C++11)
セマフォ
ラッチとバリア
(C++20)
(C++20)
future
(C++11)
(C++11)
(C++11)
(C++11)
安全なメモリ解放 (Safe Reclamation)
(C++26)
ハザードポインタ
アトミック型
(C++11)
(C++20)
アトミック型の初期化
(C++11)(C++20で非推奨)
(C++11)(C++20で非推奨)
メモリオーダー
(C++11)(C++26で非推奨)
アトミック操作のためのフリー関数
アトミックフラグのためのフリー関数
 
 
void lock_shared();
(C++17以降)

ミューテックスの共有所有権を取得します。他のスレッドがミューテックスを排他的所有権で保持している場合、lock_sharedの呼び出しは、共有所有権を取得できるまで実行をブロックします。

lock_sharedが、既にどのモード(排他または共有)でもミューテックスを所有しているスレッドによって呼び出された場合、動作は未定義です。

実装定義された最大数を超える共有所有者が既にミューテックスを共有モードでロックしている場合、lock_sharedは共有所有者の数が減少するまで実行をブロックします。所有者の最大数は少なくとも10000であることが保証されています。

同じミューテックスに対する以前のunlock()操作は、この操作とstd::memory_orderで定義されるように同期します。

目次

[編集] パラメータ

(なし)

[編集] 戻り値

(なし)

[編集] 例外

エラーが発生した場合、および lock がその仕様を満たすのを妨げる基盤となるオペレーティングシステムからのエラーを含め、std::system_error をスローします。例外がスローされた場合、ミューテックスはロックされません。

[編集] 注意

lock_shared()は通常直接呼び出されません:共有ロックの管理にはstd::shared_lockが使用されます。

[編集]

#include <chrono>
#include <iostream>
#include <mutex>
#include <shared_mutex>
#include <syncstream>
#include <thread>
#include <vector>
 
std::mutex stream_mutx;
void print(auto v)
{
    std::unique_lock<std::mutex> lock(stream_mutx);
    std::cout << std::this_thread::get_id() << " saw: ";
    for (auto e : v)
        std::cout << e << ' ';
    std::cout << '\n';
}
 
int main()
{
    using namespace std::chrono_literals;
    constexpr int N_READERS = 5;
    constexpr int LAST = -999;
 
    std::shared_mutex smtx;
    int product = 0;
 
    auto writer = [&smtx, &product](int start, int end)
    {
        for (int i = start; i < end; ++i)
        {
            auto data = i;            
            {
                std::unique_lock<std::shared_mutex> lock(smtx);
                product = data;
            } 
            std::this_thread::sleep_for(3ms);
        }
 
        smtx.lock(); // lock manually
        product = LAST;
        smtx.unlock();
    };
 
    auto reader = [&smtx, &product]()
    {
        int data = 0;
        std::vector<int> seen;
        do
        {
            {
                smtx.lock_shared(); // better to use: std::shared_lock lock(smtx);
                data = product;
                smtx.unlock_shared();
            }                                   
 
            seen.push_back(data);
            std::this_thread::sleep_for(2ms);
        }
        while (data != LAST);
 
        print(seen);
    };
 
    std::vector<std::thread> threads;
    threads.emplace_back(writer, 1, 13);
    threads.emplace_back(writer, 42, 52);
 
    for (int i = 0; i < N_READERS; ++i)
        threads.emplace_back(reader);
 
    for (auto&& t : threads)
        t.join();
}

実行結果の例

127755840 saw: 43 3 3 4 46 5 6 7 7 8 9 51 10 11 11 12 -999
144541248 saw: 2 44 3 4 46 5 6 7 7 8 9 51 10 11 11 12 -999
110970432 saw: 42 2 3 45 4 5 47 6 7 8 8 9 10 11 11 12 -999
119363136 saw: 42 2 3 4 46 5 6 7 7 8 9 9 10 11 11 12 12 -999
136148544 saw: 2 44 3 4 46 5 6 48 7 8 9 51 10 11 11 12 12 -999

[編集] 関連項目

ミューテックスをロックします。ミューテックスが利用できない場合はブロックします
(public メンバ関数) [編集]
共有所有権のためにミューテックスをロックしようとします。ミューテックスが利用できない場合は戻ります
(public メンバ関数) [編集]
ミューテックスをアンロックします (共有所有権)
(public メンバ関数) [編集]
English 日本語 中文(简体) 中文(繁體)