マルチスレッドの競合
プロセスの複数のスレッドは、コード セグメント、ヒープ スペース、データ セグメント、開いているファイル、およびその他のリソースなどのプロセス リソースを共有できます. 複数のスレッドが共有リソースをめぐって競合する場合、効果的な対策が講じられていないと、共有が発生します. データ クラッター.
次のコードは 2 つのスレッドを作成し、それぞれi
が
#include <iostream>
#include <thread>
using namespace std;
int num = 0;
void test()
{
for (int j = 0; j < 1000; j++) {
num++;
}
}
int main()
{
cout << "Start two threads." << endl;
thread thread_test1(test);
thread thread_test2(test);
thread_test1.join();
thread_test2.join();
cout << "two thread joined." << endl;
cout << "Now num is " << num << endl;
return 0;
}
コンソール出力
Start two threads.
two thread joined.
Now num is 1543
Start two threads.
two thread joined.
Now num is 2000
各実行の結果が必ずしも一致しないことがわかります。2000
クリティカル セクション
重要なリソースで動作するこのコードをマルチスレッドで実行すると、競合状態が発生する可能性があるため、このコードはクリティカル セクションと呼ばれます。
Windows
中間クリティカル セクションには、次の 4 つの重要な機能が含まれます。
#include <string>
#include <iostream>
#include <process.h>
#include <windows.h>
using namespace std;
//定义一个临界区
CRITICAL_SECTION g_cs;
int num = 0;
//线程绑定的函数返回值和参数是确定的,而且一定要__stdcall
unsigned __stdcall test(void* param)
{
EnterCriticalSection(&g_cs);//进入临界区,如果有其他线程则等待
for (int j = 0; j < 1000; j++) {
num++;
}
cout << *(string*)(param) << endl;
LeaveCriticalSection(&g_cs);//退出临界区,其他线程可以进来了
return 1;
}
int main()
{
//初始化临界区
InitializeCriticalSection(&g_cs);
HANDLE hth1, hth2, hth3;
string s1 = "first", s2 = "second";
//创建线程
hth1 = (HANDLE)_beginthreadex(NULL, 0, test, &s1, 0, NULL);
hth2 = (HANDLE)_beginthreadex(NULL, 0, test, &s2, 0, NULL);
//等待子线程结束
WaitForSingleObject(hth1, INFINITE);
WaitForSingleObject(hth2, INFINITE);
//一定要记得关闭线程句柄
CloseHandle(hth1);
CloseHandle(hth2);
cout << "Now num is " << num << endl;
//删除临界区
DeleteCriticalSection(&g_cs);
}
出力結果
second
first
Now num is 2000