ホームページ  >  記事  >  バックエンド開発  >  C++ クラス設計でスレッド セーフを実装するにはどうすればよいですか?

C++ クラス設計でスレッド セーフを実装するにはどうすればよいですか?

WBOY
WBOYオリジナル
2024-06-03 18:48:091027ブラウズ

スレッドの安全性を実現するには、C++ には 2 つの方法があります。 ミューテックスを使用してクリティカル セクションを保護し、一度に 1 つのスレッドのみがアクセスできるようにします。アトミック操作を使用すると、操作は分割できない方法で実行され、同時アクセスの問題が排除されます。

C++ クラス設計でスレッド セーフを実装するにはどうすればよいですか?

C++ クラス設計でのスレッド セーフの実装

はじめに

マルチスレッド環境では、データのスレッド セーフを確保することが重要です。 C++ でこれを実現するには、いくつかの方法があります。この記事では、ミューテックスとアトミック操作を使用してスレッドセーフなクラスを設計する方法について説明します。

ミューテックス

ミューテックスは、一度に 1 つのスレッドのみがクリティカル セクションにアクセスできるようにするロック メカニズムです。スレッドがクリティカル セクションに入ると、ミューテックスの所有権を取得します。クリティカル セクションに入ろうとする他のスレッドは、そのスレッドがミューテックスを解放するまでブロックされます。

class ThreadSafeCounter {
private:
    std::mutex m_mutex;
    int m_count;

public:
    void increment() {
        std::lock_guard<std::mutex> lock(m_mutex);
        ++m_count;
    }

    int get() {
        std::lock_guard<std::mutex> lock(m_mutex);
        return m_count;
    }
};

上記の例では、increment() メソッドと get() メソッドの両方が、標準ライブラリの std::mutex を使用して、重要地区を守る。 1 つのスレッドがカウントを更新している間、他のスレッドは同時に increment() メソッドに入ることができません。 increment()get() 方法都使用标准库中的 std::mutex 保护临界区。当一个线程正在更新计数时,其他线程无法同时进入 increment() 方法。

原子操作

原子操作是一种特殊类型的操作,它以不可分割的方式执行。这意味着一次只能在单个线程中执行这些操作,从而消除了并发访问引发的问题。C++11 中引入了 std::atomic 库,它提供了用于原子操作的类。

class ThreadSafeCounterAtomic {
private:
    std::atomic<int> m_count;

public:
    void increment() {
        ++m_count;
    }

    int get() {
        return m_count.load();
    }
};

在本例中,m_count 是一个原子整数,可以安全地从多个线程中进行增量和获取。std::atomic<int>::load()</int>

アトミック操作

アトミック操作は、分割できない方法で実行される特別なタイプの操作です。これは、これらの操作は一度に 1 つのスレッドでのみ実行できることを意味し、同時アクセスによって引き起こされる問題を排除します。 C++11 では、アトミック操作のクラスを提供する std::atomic ライブラリが導入されました。

#include <thread>

int main() {
    std::unique_ptr<ThreadSafeCounter> counter = std::make_unique<ThreadSafeCounter>();

    std::vector<std::thread> threads(10);
    for (auto& thread : threads) {
        thread = std::thread([&] {
            for (int i = 0; i < 1000000; ++i) {
                counter->increment();
            }
        });
    }

    for (auto& thread : threads) {
        thread.join();
    }

    std::cout << "最终计数:" << counter->get() << std::endl;
}

この場合、m_count は、安全にインクリメントして複数のスレッドから取得できるアトミックな整数です。 std::atomic<int>::load()</int> メソッドは、スレッドセーフな方法でアトミック整数の値を取得します。

実際的なケース

複数のスレッドから並行して更新する必要がある共有カウンタの例を考えてみましょう:

rrreee

このプログラムでは、10 個のスレッドから並行してカウンタを更新し、最終的なカウントをメインスレッド。ミューテックスにより、カウンタは常に最大 1 つのスレッドによってのみ更新されることが保証され、スレッドの安全性が確保されます。 🎜🎜🎜結論🎜🎜🎜スレッドセーフな C++ クラスは、ミューテックスとアトミック操作を使用して設計できます。ミューテックスはシリアル アクセスを必要とするクリティカル セクションの保護に適しており、アトミック操作はシリアル アクセスを必要とせず、アトミックに実行できる操作に適しています。 🎜

以上がC++ クラス設計でスレッド セーフを実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。