CreateThread参数值意外更改
CreateThread parameter value changes unexpectedly
我试图创建4个线程,以便在我的4个CPU内核上同时运行一个函数。我调用的函数将根据val
变量值更改一些循环偏移。
我试过这个,但它没有正确地增加val
计数器,一些线程报告相同的值,它似乎随机变化:
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);
但这似乎很有效:
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);
这可能是什么原因,以及如何正确地为线程提供一些参数?
这是我的功能:
DWORD WINAPI my_thread_1(void *params){
int val = *(int *)params;
...
}
这之所以失败,只是因为在第一个示例中,您将指针传递到所有4个线程的相同内存位置。在传递指针之前递增值这一事实无关紧要,因为内存位置保持不变。
在第二个示例中,您将4个互斥指针传递给4个线程。因此,线程都读取独立的值。
您可以稍微重组代码以帮助提高可维护性和灵活性:
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);
在第一种情况下,将同一对象传递给所有线程。在第二种情况下,您正在传递不同的对象。
在这两种情况下,都存在一个潜在的问题,即如果创建线程的函数返回,那么所有创建的线程都将具有指向已不存在的int
的指针,因为所有int
对象都是创建线程的功能的本地对象。这会调用未定义的行为。
所以,如果函数不等待并返回,那么在这种情况下,不应该将指针传递给本地对象,而应该传递动态分配的对象:
int *v1 = new int;
threads[0] = CreateThread(0, 0, my_thread_1, v1 , 0, 0);
多个线程同时访问同一内存。您应该使用互斥或信号量来独占访问关键部分中的变量。
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- boost::p rogram_options 在指定意外的位置参数时不报告任何错误
- C++中出现意外的编译错误:将默认值传递给函数参数
- 具有模板参数推导的构造函数意外执行
- 意外参数通过使用STL数字的顺序
- glDrawArrays的意外行为-参数顺序错误会产生所需的图像
- 意外错误"no matching function for call to",需要没有参数的构造函数
- 依赖于参数的查找在来自另一个命名空间的别名类型上意外行为
- 将构造函数与 const char * 作为参数链接会产生意外的结果
- 使用引用参数传递引用意外行为
- CreateThread参数值意外更改
- 使用getter函数传递引用参数时出现意外行为
- c++方法参数给出意外输出
- C++ 具有特征的瓦拉迪试时,带有参数列表的重载函数会产生意外的结果
- 使用默认函数模板参数的意外重载解析
- 在程序中使用非类型模板参数而未给局部变量赋值时,会导致意外结果
- 为什么我会在意外标记附近出现语法错误?命令行参数