Вы предполагаете, что ОС действительно поддерживает это. Windows не делает. У него нет никаких гарантий в отношении графика, кроме голодания.
Итак, вам нужно установить переменную флага, чтобы каждый поток изменил ее, чтобы позволить другому потоку работать. Например, если это правда - запустить, если это ложно - освободить мьютекс и некоторое время спать, а другой поток - с точностью до наоборот. Здесь важен сон, чтобы избежать голода и тупика. Я думаю, что это может быть Sleep (0) (проверьте, означает ли это «yield» в Windows, я не уверен).
Конечно, проверки должны выполняться при взятии мьютекса, и в конце выполнения каждый поток изменит переменную на противоположную - чтобы позволить другому потоку запускаться и блокироваться, пока другой поток не запустится и меняет его обратно.
Его можно легко изменить на более чем 2 потока, сделав переменную счетчиком по модулю количества потоков, и каждый поток увеличит значение в конце цикла и проверив значение по модулю как номер потока в порядке исполнения в начале.
1010 * редактировать *
volatile bool flag = false;
DWORD WINAPI ThreadFunc1(LPVOID lpParam)
{
int* nCalcNumber = static_cast<int*>(lpParam);
for (int i = 0; i < *nCalcNumber; /*no-op*/;)
{
WaitForSingleObject(g_hMutex1, INFINITE);
if (flag) {Sleep(0); continue;}
cout << "Func 1" << endl;
flag = true;
i++;
ReleaseMutex(g_hMutex1);
}
return 0;
}
DWORD WINAPI ThreadFunc2(LPVOID lpParam)
{
int* nCalcNumber = static_cast<int*>(lpParam);
for (int i = 0; i < *nCalcNumber; /*no-op*/;)
{
WaitForSingleObject(g_hMutex1, INFINITE);
if (!flag) {Sleep(0); continue;}
cout << "Func 2" << endl;
flag = false;
i++;
ReleaseMutex(g_hMutex1);
}
return 0;
}