1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

グローバル変数に排他制御を行わなかったどうなるのか

Posted at

排他制御とは

同じデータに対して、同時に更新処理が行われる際に、データの整合性を保つために行う処理のことである

実際にやってみた

排他制御を行わない場合

メインプロセス

# 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
排他制御を行った場合は欲しかった結果を得られることが出来ました。
排他制御を行わない場合でもコンパイル時、実行時にエラーが起こるわけでは気を付ける必要がありますね。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?