#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <windows.h>
#include <process.h>
using namespace std;
HANDLE ghEvents;
struct DataStructure
{
int r[2];
int h;
};
unsigned __stdcall f2(void *p)
{
DataStructure *input = (DataStructure *)p;
int i = (int)input->h;
cout <<i<<endl;
}
int main()
{
HANDLE hThread[8];
DWORD i, dwEvent, dwThreadID;
unsigned threadID;
DataStructure input;
ghEvents = CreateEvent(NULL,FALSE,FALSE,NULL);
for (int i = 0; i < 8; i++)
{
input.h=i;
hThread[i] = (HANDLE)_beginthreadex( NULL, 0, f2, (void*)&input, 0, &threadID );
}
dwEvent = WaitForMultipleObjects(8,hThread,TRUE,INFINITE);
CloseHandle(ghEvents);
for (int i = 0; i < 8; i++)
{
CloseHandle( hThread[i] );
}
cin.get();
return 0;
}
输出为77777777而不是12345678.
我知道我必须通过值传递输入而不是引用但是它一直给我一个错误信息,这是什么方法呢?
答案 0 :(得分:1)
您为每个帖子提供相同DataStructure
的地址。您的输出是不确定的。根据每个线程何时运行,它们可以在该循环的另一次迭代之前,期间或之后读取。这意味着,当线程旋转并且访问input->h
时,主线程可能已经继续并将input.h
更改为下一次迭代。
示例:
input.h
设置为0。input
作为参数启动线程0。input.h
设置为1。input
作为参数启动线程1。input.h
设置为2。input
作为参数启动线程2。 input.h
设置为3。input->h
读为3。input
作为参数启动线程3。 input->h
读为3。input.h
设置为4。input->h
读为4。input->h
读为4。input->h
读为4。最终输出:3344
为每个线程提供不同的DataStructure
,以便它们不会尝试从同一个内存地址读取。这样,没有竞争条件。该术语指的是线程启动和执行顺序无法保证,因此如果线程在没有同步的情况下访问相同的资源,它们将“竞争”。
答案 1 :(得分:1)
这是我之前的回答之后,如果在编译时已知线程数,这是一个更好的解决方案。
DataStructure input[8];
...
for (int i = 0; i < 8; i++)
{
input[i].h=i;
hThread[i] = (HANDLE)_beginthreadex( NULL, 0, f2, (void*)&input[i], 0, &threadID );
}
你需要返回一个值:
unsigned __stdcall f2(void *p)
{
DataStructure *input = (DataStructure *)p;
int i = input->h;
cout <<i<<endl;
return 0;
}
答案 2 :(得分:0)
当你为每个线程覆盖input.h的值时,你需要为每个线程创建数据结构。
所以要修复,将其更改为
DataStructure *input;
...
for (int i = 0; i < 8; i++)
{
input = new DataStructure ;
input->h=i;
hThread[i] = (HANDLE)_beginthreadex( NULL, 0, f2, (void*)input, 0, &threadID );
}
为避免内存泄漏,请使用f2函数删除输入,即
unsigned __stdcall f2(void *p)
{
DataStructure *input = (DataStructure *)p;
int i = input->h;
cout <<i<<endl;
delete input;
return 0;
}
note 如果在编译时线程数未知,此解决方案使用动态内存分配,这是一个很好的解决方案。如果已知线程数,请参阅我的其他答案。
答案 3 :(得分:0)
第一点是:
对于正在传递给多个线程的数据结构,没有适当的同步,虽然这些线程正在对它做一些事情,但您已经完成了循环的下一次迭代并且正在更改数据结构的价值。
在循环内创建新的数据结构,以避免出现同步问题。