【发布时间】:2015-03-24 03:16:06
【问题描述】:
我有一个关于我正在编写的程序的问题,它需要一些多线程。线程函数需要几个参数,我通过以下方式传递:
- 为参数定义了一个结构(我们称之为 ThreadDataStruct)
- 初始化此结构并填充值(调用我们的 ThreadDataStruct 实例 THREAD_DATA)
- 通过将 lpParameter 设置为指向结构 (&THREAD_DATA) 的指针,在 CreateThread 期间将值传递给我的线程
- 在线程函数中将 LPVOID 重新转换为 ThreadDataStruct
问题是我创建线程的函数在调用 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;
}
我是否需要另一种方法来安全地传递参数?
【问题讨论】:
-
是的,你有一个竞争条件;是的,您需要有一种不同的方式将参数安全地传递给函数。传递给线程函数的变量(通常)是按地址传递的,因此只要线程需要访问它,它就需要持续存在。在您的代码中,函数返回,这意味着该变量不再有效,所以一切都乱套了。
-
@JonathanLeffler 感谢您澄清这一点。有哪些方法可以安全地传递参数?我想我可以在 CreateThread 之后放置一个 Sleep(5000),但这显然不是最好的方法。
-
一种选择是让
Function()等待线程在它返回之前完成。另一种选择是让Function()等待一个信号量,当它完成读取其控制数据时,ThreadFunction()会在信号量上发出信号。另一种选择,可能是最好的,是让调用Function()的函数传入一个可以使用的ThreadDataStruct *,并让它保持这个状态直到所有线程都终止。 [...继续...] -
[…continuation…] 所以,如果是
main()调用Function(),那么main()可能有一个ThreadDataStruct thread_params[32];数组,它可以通过&thread_params[i]到ith 调用到Function()(可能在一个循环内)。毫无疑问,还有其他等效技术可用;这些立即浮现在脑海中。但是,通常,控制代码具有某种可用的数据结构数组,并将该数组的元素之一传递给线程启动函数的每次调用。 -
@JonathanLeffler 感谢您的帮助
标签: c multithreading