我对我正在编写的程序有疑问,需要一些多线程。线程函数需要几个参数,我通过执行以下操作来传递这些参数:
问题是我创建线程的函数在调用CreateThread后直接返回。我的问题是:创建线程后可以很快返回导致线程无法获取其参数?如果结构是在函数中创建的,然后函数返回,那么如果线程函数的参数不能足够快,那么它的参数会被破坏吗?
这是一些显示我的意思的POC:
我们结构的定义:
typedef struct ThreadDataStruct
{
int Number;
};
我们在里面运行的功能:
void Function()
{
ThreadDataStruct THREAD_DATA;
THREAD_DATA.Number = 1;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunction, &THREAD_DATA, 0, NULL);
return;
}
我们的线程功能:
void ThreadFunction(LPVOID lpParam)
{
ThreadDataStruct THREAD_DATA = *(ThreadDataStruct *)lpParam;
int NumberFromStruct = THREAD_DATA.Number;
return;
}
我是否需要找到另一种安全传递参数的方法?
答案 0 :(得分:0)
将评论转移到答案中。
是的,你有竞争条件;是的,你需要有一种不同的方式将参数安全地传递给函数。传递给线程函数的变量(通常)通过地址传递,因此只要线程需要访问它,它就需要持续。在你的代码中,函数返回,这意味着变量不再有效,所以所有的地狱都会破裂。
感谢你清理它。有什么方法可以安全地传递参数?我想我可以在
Sleep(5000)
之后加CreateThread()
,但这显然不是最好的方法。
一个选项是让Function()
等待线程在返回之前完成。另一个选择是让Function()
等待信号量,ThreadFunction()
会在信号量读完控制数据时发出信号。
另一种选择,可能是最好的选择,是让调用Function()
的函数在可以使用的ThreadDataStruct *
中传递,并让它保持这种状态直到所有线程都终止。因此,如果main()
调用Function()
,那么main()
可能会有一个ThreadDataStruct thread_params[32];
数组,并且可以将&thread_params[i]
传递给i
th 调用Function()
(可能在循环内)。
void Function(ThreadDataStruct *THREAD_DATA)
{
THREAD_DATA->Number = 1;
CreateThread(NULL, 0, ThreadFunction, THREAD_DATA, 0, NULL);
}
int main(void)
{
ThreadDataStruct thread_params[32];
for (int i = 0; i < 32; i++)
Function(&thread_params[i]);
…code to wait for threads to exit…
}
Function()
中的更改包括:
&THREAD_DATA
。ThreadFunction()
CreateThread()
调用return;
是正确的类型。void
函数末尾的{{1}}没有任何美德。毫无疑问,还有其他同等技术可用;这些立即浮现在脑海中。但是,通常情况下,控制代码具有某种可用的数据结构数组,并将数组的一个元素传递给每个线程启动函数的调用。