Почему одинаковая задержка в одних и тех же потоках влияет на результат? - PullRequest
0 голосов
/ 09 апреля 2019

У меня есть 2 несинхронизированных потока, которые изменяют глобальную переменную. Каждый поток имеет 12 итераций. Перед командой модификации каждый поток имеет задержку в 1 мс. В результате глобальная переменная равна 112, что логично, поскольку потоки изменяют ее одновременно, НО, если вы удалите задержку в обоих потоках, то один из них будет впереди другого потока, так что другой поток получит текущее значение глобальной переменной. Почему это происходит, когда включены задержки?

#include "stdafx.h" 
#include <windows.h> 
#include <iostream> 
#include <omp.h>
using namespace std;

int global = 100;
HANDLE ht1, ht2; 
DWORD WINAPI ThreadProc1(LPVOID lpParameter ) { 
    int i, j;   
    for (j=1; j <= 12; j++)    {
        i = global;      
        i++;     
        Sleep (1);  //Delay before modifying global variable
        global = i; 
        printf_s( "%4s %4d \n", " 1 th", i );    
    } 
    return 0;  
}
DWORD WINAPI ThreadProc2 (LPVOID lpParameter) { 
    int i, j; 
    for (j=1; j <= 12; j++)    {   
        i = global;      
        i++;     
        Sleep (1);  //Delay before modifying global variable     
        global = i;
        printf_s( "%4s %4d %4d \n", " 2 th", i, j );     
    } 
    return 0; 
} 
int _tmain(int argc, _TCHAR* argv[]) { 
    HANDLE msh[2]; 
    ht1 = CreateThread(NULL, 0, &ThreadProc1, NULL, 0, NULL); 
    ht2 = CreateThread(NULL, 0, &ThreadProc2, NULL, 0, NULL); 
    msh[0] = ht1; 
    msh[1] = ht2;
    WaitForMultipleObjects(2,msh,TRUE, INFINITE);
    return 0; 
} 

задержка результата https://i.imgur.com/EMOQfTj.png

результат без задержки https://i.imgur.com/Ilgz824.png

1 Ответ

2 голосов
/ 10 апреля 2019

На основании планирования потоков вашей операционной системы, при добавлении задержки все два потока выполняют i = global, глобальное значение одинаково для двух потоков. Так что это просто увеличение на 12. Когда нет задержки, код:

i = global;      
i++;     
global = i;

не был прерван, что эквивалентно global++ здесь. Таким образом, результат равен 100 + 12 * 2 = 124.

...