2013-11-27 86 views
-1

我喜欢这个通过CreateThread传递参数失败?

starts代码是DWORD32

threads一个数组的HANDLE

void initThreads(HANDLE* threads, int size) 
{ 
    DWORD32* starts = (DWORD32*)malloc(sizeof(DWORD32) * size); 
    for (int i = 0; i < size; ++i) 
    { 
     starts[i] = num_steps/numThreads * i; 
    } 
    for (int i = 0; i < size; ++i) 
    { 
     DWORD32* para = starts + i; 
     printf("create %ld\n", *para); 
     threads[i] = CreateThread(NULL, 0, portionCal, (void*)para, 0, NULL); 
    } 
    free(starts); 
} 

DWORD WINAPI portionCal(LPVOID pArg) 
{ 
    double x, portionSum = 0.0; 
    DWORD32 start = *(DWORD32*)pArg; 
    printf("start at %d\n", start); 
} 

一个数组,但结果是

create 0 
create 25000000 
start at 0 
create 50000000 
create 75000000 
start at 50000000 
start at -17891602 
start at 25000000 

为什么结果是这样的?

+0

我回滚你的问题的编辑。你问了这个问题。你对这个问题有两个答案。在问题中重复回答根本没有意义。 –

回答

2

我们看不到开始的范围但是这可以从失败中猜到。它可能是一个局部变量,在线程开始运行时很久没有了。所以你只会阅读垃圾。您需要一个稳定的指针,从全局变量或malloc()中获取一个。

编辑完成后:不要像这样调用free()。它必须保持稳定,直到全部线程完成使用它。您可以考虑使用InterlockedDecrement()对其进行计数。

+0

启动是没有本地价值的,我把完整的代码放在问题 – CLS

+0

谢谢你的回答,我发现它有什么问题 – CLS

1

创建线程后立即释放starts阵列。所以会发生什么是线程被传递给内存的指针,这些指针可能在线程有机会读取之前被释放。如果发生这种情况,结果的行为是未定义的。

您可以通过确保指针引用的内存的生存期延长超出线程的寿命来解决问题。通常情况下,通过为每个线程分配堆数据并在线程调用free时执行该操作。

在这种情况下,解决问题的更简单方法是传递整数值而不是指向它的指针。就像这样:

threads[i] = CreateThread(NULL, 0, portionCal, (void*)starts[i], 0, NULL); 

而且在你的线程:

DWORD32 start = (DWORD32)pArg; 
+0

谢谢我发现错误,我在线程init之前立即释放启动程序 – CLS

+0

你发现错误?呃,你看过我的回答了吗? –