conflicto de subprocesos múltiples
Múltiples subprocesos de un proceso pueden compartir recursos de proceso, como segmento de código, espacio de almacenamiento dinámico, segmento de datos, archivos abiertos y otros recursos. Cuando varios subprocesos compiten por recursos compartidos, si no se toman medidas efectivas, se compartirán. Desorden de datos.
El siguiente código crea dos subprocesos, cada uno de los i
cuales 1000 veces
#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;
}
salida de la consola
Start two threads.
two thread joined.
Now num is 1543
Start two threads.
two thread joined.
Now num is 2000
Se puede ver que el resultado de cada corrida no es necesariamente2000
sección crítica
Debido a que la ejecución de subprocesos múltiples de este código que opera en un recurso crítico puede conducir a una condición de carrera, este código se denomina sección crítica.
Windows
La sección crítica intermedia implica cuatro funciones clave:
- InitializeCriticalSectionInitializeCriticalSection
- Entrar en la sección crítica
- DejarSecciónCrítica
- DeleteCriticalSection
#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);
}
resultado de salida
second
first
Now num is 2000