C におけるマルチスレッド同期の問題と解決策の概要
マルチスレッド プログラミングは、プログラムのパフォーマンスと効率の向上に役立つ同時プログラミング手法です。ただし、マルチスレッド プログラミングには一連の課題や問題も伴います。その中で最も顕著なものはマルチスレッドの同期です。この記事では、C におけるマルチスレッド同期の問題の概要を示し、いくつかの一般的な解決策を紹介します。同時に、これらの回避策の実際の動作を示す具体的なコード例をいくつか提供します。
2.1 Mutex (ミューテックス)
Mutex は、C 標準ライブラリでスレッド同期を実現するために使用されるメカニズムです。これは、同時に 1 つのスレッドのみが共有データにアクセスできるという単純な原則に基づいています。スレッドが共有データにアクセスする場合は、まずミューテックスをロックして他のスレッドによるアクセスをブロックし、次に実行後にミューテックスを解放して他のスレッドがアクセスできるようにする必要があります。
以下は、ミューテックスを使用して競合状態の問題を解決するサンプル コードです:
#include <iostream> #include <thread> #include <mutex> std::mutex mtx; int count = 0; void increment() { std::lock_guard<std::mutex> lock(mtx); count++; } int main() { std::thread t1(increment); std::thread t2(increment); t1.join(); t2.join(); std::cout << "Count: " << count << std::endl; return 0; }
上記のコードでは、std::mutex を使用してカウントへのスレッドセーフなアクセスを保証します。 std::lock_guard を使用してミューテックスをロックし、同時に 1 つのスレッドのみが count 変数にアクセスできるようにします。
2.2 条件変数
条件変数は、スレッド同期のためのもう 1 つのメカニズムです。これにより、あるスレッドは実行を続行する前に、他のスレッドが特定の条件を満たすのを待つことができます。スレッドが条件変数の wait 関数を呼び出すと、他のスレッドが条件変数の Notice 関数または Notify_all 関数を呼び出して待機中のスレッドをウェイクアップするまで、そのスレッドはブロックされます。
以下は、条件変数を使用してデッドロック問題を解決するサンプル コードです。
#include <iostream> #include <thread> #include <mutex> #include <condition_variable> std::mutex mtx; std::condition_variable cv; bool ready = false; void thread1() { std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, [] { return ready; }); std::cout << "Thread 1: Ready!" << std::endl; } void thread2() { std::this_thread::sleep_for(std::chrono::seconds(1)); std::unique_lock<std::mutex> lock(mtx); ready = true; cv.notify_one(); } int main() { std::thread t1(thread1); std::thread t2(thread2); t1.join(); t2.join(); return 0; }
上記のコードでは、thread1 スレッドは実行を続行する前に、ready 変数が true になるまで待機します。 thread2 スレッドは、1 秒待機した後にreadyをtrueに設定し、条件変数のnotify_one関数を通じて待機中のスレッドをウェイクアップします。
2.3 アトミック操作 (Atomic)
アトミック操作は、ロックなしでスレッドセーフなアクセスを実現できる特別な操作です。 C は、アトミック操作をサポートする std::atomic テンプレートを提供します。アトミック操作を使用すると、競合状態の問題を回避し、コードのパフォーマンスを向上させることができます。
以下は、アトミック操作を使用して競合状態の問題を解決するサンプル コードです:
#include <iostream> #include <thread> #include <atomic> std::atomic<int> count(0); void increment() { count.fetch_add(1); } int main() { std::thread t1(increment); std::thread t2(increment); t1.join(); t2.join(); std::cout << "Count: " << count << std::endl; return 0; }
上記のコードでは、std::atomic
この記事では、上記の 3 つの一般的なソリューションを紹介し、それらの実際のアプリケーションを示す具体的なコード例を示します。読者が C のマルチスレッド同期の問題をより深く理解し、それを実際のマルチスレッド プログラミングに柔軟に適用できるようになることを願っています。
以上がC++ におけるマルチスレッド同期の問題と解決策の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。