排他制御とは
同じデータに対して、同時に更新処理が行われる際に、データの整合性を保つために行う処理のことである
実際にやってみた
排他制御を行わない場合
メインプロセス
# include <iostream>
# include <thread>
# include <chrono>
void countThread();
int count = 0;
int main()
{
std::thread countThread1(countThread);
std::thread countThread2(countThread);
countThread1.join();
countThread2.join();
std::cout << "count == " << count << "\n";
}
子スレッド
void countThread()
{
for (int i = 0; i < 80000; i++)
{
count++;
if ((i % 2000) == 0)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
}
結果
count == 141471
80000回のカウントアップを2スレッドで行っているので160000になるはずですが、競合が発生し18529回カウントアップに失敗しています。
排他制御をした場合
今度は排他制御を行い、同様の処理を実行します。
今回はmutexを行い、排他制御します。
メインプロセスと子スレッドを以下のように変更します。
メインプロセス
# include <iostream>
# include <thread>
# include <chrono>
# include <mutex>
void countThread();
int count = 0;
std::mutex countMutex;
int main()
{
std::thread countThread1(countThread);
std::thread countThread2(countThread);
countThread1.join();
countThread2.join();
std::cout << "count == " << count << "\n";
}
子スレッド
void countThread()
{
for (int i = 0; i < 80000; i++)
{
countMutex.lock();
count++;
countMutex.unlock();
if ((i % 2000) == 0)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
}
結果
count == 160000
排他制御を行った場合は欲しかった結果を得られることが出来ました。
排他制御を行わない場合でもコンパイル時、実行時にエラーが起こるわけでは気を付ける必要がありますね。