【发布时间】:2021-11-11 14:24:06
【问题描述】:
我的代码有问题:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <windows.h>
#include <string.h>
#include <math.h>
HANDLE event;
HANDLE mutex;
int runner = 0;
DWORD WINAPI thread_fun(LPVOID lpParam) {
int* data = (int*)lpParam;
for (int j = 0; j < 4; j++) { //this loop necessary in order to reproduce the issue
if ((data[2] + 1) == data[0]) { // if it is last thread
while (1) {
WaitForSingleObject(mutex, INFINITE);
if (runner == data[0] - 1) { // if all other thread reach event break
ReleaseMutex(mutex);
break;
}
printf("Run:%d\n", runner);
ReleaseMutex(mutex);
Sleep(10);
}
printf("Check Done:<<%d>>\n", data[2]);
runner = 0;
PulseEvent(event); // let all other threads continue
}
else { // if it is not last thread
WaitForSingleObject(mutex, INFINITE);
runner++;
ReleaseMutex(mutex);
printf("Wait:<<%d>>\n", data[2]);
WaitForSingleObject(event, INFINITE); // wait till all other threads reach this stage
printf("Exit:<<%d>>\n", data[2]);
}
}
return 0;
}
int main()
{
event = CreateEvent(NULL, TRUE, FALSE, NULL);
mutex = CreateMutex(NULL, FALSE, NULL);
SetEvent(event);
int data[3] = {2,8}; //0 amount of threads //1 amount of numbers
HANDLE t[10000];
int ThreadData[1000][3];
for (int i = 0; i < data[0]; i++) {
memcpy(ThreadData[i], data, sizeof(int) * 2); // copy amount of threads and amount of numbers to the threads data
ThreadData[i][2] = i; // creat threads id
LPVOID ThreadsData = (LPVOID)(&ThreadData[i]);
t[i] = CreateThread(0, 0, thread_fun, ThreadsData, 0, NULL);
if (t[i] == NULL)return 0;
}
while (1) {
DWORD res = WaitForMultipleObjects(data[0], t, true, 1000);
if (res != WAIT_TIMEOUT) break;
}
for (int i = 0; i < data[0]; i++)CloseHandle(t[i]); // close all threads
CloseHandle(event); // close event
CloseHandle(mutex); //close mutex
printf("Done");
}
主要思想是等到除一个之外的所有线程都到达事件并在那里等待,同时最后一个线程必须释放它们等待。
但是代码不能可靠地工作。 10 次中有 1 次正确结束,9 次卡在 while(1) 中。在不同的尝试中,while (printf("Run:%d\n", runner);) 中的printf 会打印不同数量的跑步者(0 和 3)。
可能是什么问题?
【问题讨论】:
-
在您的问题中,您声明
data[2] + 1等于当前线程的数量。这是否意味着data为所有线程引用不同的内存位置? -
@AndreasWenzel 不,每个线程都有自己的数据:
int ThreadData[1000][3]; ... memcpy(ThreadData[i], data, sizeof(int) * 2); ThreadData[i][2] = i; LPVOID ThreadsData = (LPVOID)(&ThreadData[i]); t[i] = CreateThread(0, 0, thread_fun, ThreadsData, 0, NULL); -
我在发布的代码中没有发现任何问题。因此,我怀疑问题出在您没有向我们展示的代码中。如果可能,请提供问题的minimal reproducible example。
-
@AndreasWenzel 我添加了我的代码的最小示例
-
您是否验证了新的最小代码确实重现了问题?它是否仍然为
runner打印5?
标签: c++ multithreading winapi events mutex