Un estudio preliminar de la sección crítica de Windows

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 icuales 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.

WindowsLa sección crítica intermedia implica cuatro funciones clave:

#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

Supongo que te gusta

Origin blog.csdn.net/Star_ID/article/details/126572499
Recomendado
Clasificación