首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CreateThread参数值意外更改

CreateThread参数值意外更改
EN

Stack Overflow用户
提问于 2012-01-24 02:38:34
回答 3查看 1.6K关注 0票数 3

我正在尝试创建4个线程,以便在我的4个CPU核心上同时运行一个函数。我调用的函数将根据val变量的值更改一些循环偏移量。

我试过了,但它没有正确地增加val计数器,一些线程报告相同的值,它似乎是随机变化的:

代码语言:javascript
复制
int val = 1;
threads[0] = CreateThread(0, 0, my_thread_1, &val, 0, 0);
val++;
threads[1] = CreateThread(0, 0, my_thread_1, &val, 0, 0);
val++;
threads[2] = CreateThread(0, 0, my_thread_1, &val, 0, 0);
val++;
threads[3] = CreateThread(0, 0, my_thread_1, &val, 0, 0);

但这似乎工作得很好:

代码语言:javascript
复制
int val1 = 1;
int val2 = 2;
int val3 = 3;
int val4 = 4;
threads[0] = CreateThread(0, 0, my_thread_1, &val1, 0, 0);
threads[1] = CreateThread(0, 0, my_thread_1, &val2, 0, 0);
threads[2] = CreateThread(0, 0, my_thread_1, &val3, 0, 0);
threads[3] = CreateThread(0, 0, my_thread_1, &val4, 0, 0);

这可能是什么原因,以及如何正确地为线程提供一些参数?

这是我的函数:

代码语言:javascript
复制
DWORD WINAPI my_thread_1(void *params){ 
    int val = *(int *)params;
...
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-24 02:40:57

这失败的原因很简单,因为在您的第一个示例中,您将指针传递给所有4个线程的相同内存位置。在传递指针之前递增该值的事实是无关紧要的,因为内存位置保持不变。

在你的第二个例子中,你传递了4个互斥的指向4个线程的指针。因此,所有线程都读取独立的值。

您可以稍微调整代码结构,以提高可维护性和灵活性:

代码语言:javascript
复制
int threadData[NTHREADS]; /* in the future this could be an array of structs */
HANDLE threads[NTHREADS];
int tt;

for (tt = 0; tt < NTHREADS; ++tt)
{
    threadData[tt] = tt + 1; /* placeholder for actual logic */
    threads[tt] = CreateThread(
        NULL,            /* lpThreadAttributes */
        0,               /* dwStackSize */
        my_thread_1,     /* lpStartAddress */
        &threadData[tt], /* lpParameter: each thread will receive its own data */
        0,               /* dwCreationFlags */
        NULL             /* lpThreadId */);
}

/* Since threadData and threads are local to the enclosing scope,
 * we must wait for them to finish here to ensure we don't read
 * data we no longer own
 */
WaitForMultipleObjects(NTHREADS, threads, TRUE, INFINITE);
票数 5
EN

Stack Overflow用户

发布于 2012-01-24 02:41:55

在第一种情况下,您将向所有线程传递相同的对象。在第二种情况下,您将传递不同的对象。

在这两种情况下,都存在一个潜在的问题,即如果创建线程的函数返回,那么所有创建的线程都将具有指向不再存在的int的指针,因为所有的int对象都是创建线程的函数的本地对象。这会调用未定义的行为。

因此,如果函数没有等待并返回,那么在这种情况下,您不应该将指针传递给本地对象,而应该传递动态分配的对象:

代码语言:javascript
复制
int *v1 = new int;
threads[0] = CreateThread(0, 0, my_thread_1, v1 , 0, 0);
票数 1
EN

Stack Overflow用户

发布于 2012-01-24 02:40:56

多个线程同时访问相同的内存。您应该使用互斥或信号量来独占访问临界区中的变量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8976807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档