多线程冲突
一个进程的多个线程之间是可以共享进程的资源,比如代码段、堆空间、数据段、打开的文件等资源,当多个线程竞争共享资源,如果不采取有效的措施,则会造成共享数据的混乱。
以下代码创建两个线程,它们分别对共享变量 i
自增 1 执行 1000 次
#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
中临界区涉及四个关键函数:
#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
本文含有隐藏内容,请 开通VIP 后查看