使用 _beginthreadx 将结构传递给线程
#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。
我知道我必须按值传递输入而不是引用,但它一直给我一条错误消息,正确的方法是什么?
#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;
}
The output is 77777777 instead of 12345678.
I know i have to pass the input by value and not reference but it keeps giving me an error message, what is the proper way to do it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是我之前的答案之后的结果,如果在编译时已知线程数,这是一个更好的解决方案。
并且您需要返回一个值:
This is subsequent to my previous answer as is a better solution if the number of threads is known at compile time.
And you need to return a value:
您为每个线程提供相同
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
,以便它们不会尝试从同一内存地址读取。这样,就不存在竞争条件了。该术语指的是线程启动和执行顺序无法保证的事实,因此如果线程在没有完成同步的情况下访问相同的资源,它们将“竞争”。You are giving each thread the address of the same
DataStructure
. Your output is non-deterministic. Depending on when each thread gets to run, they may read before, during, or after another iteration of that loop. Meaning, by the time the thread spins up and gets to accessinput->h
, the main thread may have already continued on and changinginput.h
to the next iteration.Example:
input.h
to 0.input
as a parameter.input.h
to 1.input
as a parameter.input.h
to 2.input
as a parameter.input.h
to 3.input->h
as 3.input
as a parameter.input->h
as 3.input.h
to 4.input->h
as 4.input->h
as 4.input->h
as 4.Final Output: 3344
Give each thread a different
DataStructure
so that they are not trying to read from the same memory address. This way, there is no race-condition. The term refers to the fact that thread start up and order of execution is not guaranteed, so if threads are accessing the same resources without synchronization being done, they will "race".第一点是:
您的数据结构没有同步,该数据结构正在传递给多个线程,并且当这些线程正在对其执行某些操作时,您已经在进行循环的下一次迭代并更改 你的数据结构的价值。
在循环内创建新的数据结构以避免出现同步问题。
First point is:
You have no synchronization in place for your datastructure which is being passed to multiple threads, and while these threads are doing something with it, you're already going through the next iteration of the loop and changing the value of your datastructure.
Create a new datastructure inside a the loop to avoid having synchronization issues.
当您为每个线程覆盖 input.h 的值时,您需要为每个线程创建数据结构。
因此,要修复,请将其更改为
为了避免内存泄漏,请使用 f2 函数删除输入,即
注意 此解决方案使用动态内存分配,如果编译时线程数未知,那么这是一个很好的解决方案。如果线程数已知,请参阅我的其他答案。
You need to create the data structure for each of the threads as you are overwriting the value of input.h for each of the threads.
So to fix, change it to
And to avoid a memory leak get the f2 function to delete the input i.e.
note This solution uses dynamic memory allocation as is good solution if the number of threads are unknown at compile time. See my other answer if the number of threads is known.