我是为了自己的娱乐修补此代码:
#include <windows.h>
#include <process.h>
#include <stdlib.h>
#include <stdio.h>
void print_message(void *param)
{
int thread_counter = *((int*)param);
printf("Thread #%irn", thread_counter);
_endthreadex(0);
}
int main()
{
unsigned thread_ID;
HANDLE thread_handle;
int thread_count = 10;
HANDLE thread_handles[thread_count];
for(int i = 0; i < thread_count; i++)
{
thread_handles[i] = (HANDLE)_beginthreadex(NULL, 0, &print_message, &i, 0, &thread_ID);
thread_handle = thread_handles[i];
}
WaitForMultipleObjects(thread_count, thread_handles, TRUE, INFINITE);
return EXIT_SUCCESS;
}
a
Output
Thread #8
Thread #10
Thread #10
Thread #10
Thread #10
Thread #10
Thread #10
Thread #10
Thread #10
Thread #10
我认为问题是我正在传达对变量i的引用,而在线程使用/操纵此引用时,for循环中的变量i正在逐渐增加。
。我如何避免竞赛条件,并将变量i的值传递给线程函数?
我也想将字符串/字符阵列传递到线程功能,但我似乎不明白如何做。
我正在使用Windows 10
不要将指针传递给 i
,传递 value 存储在 i
本身中:
void print_message(void *param)
{
int thread_counter = (intptr_t)param;
printf("Thread #%irn", thread_counter);
_endthreadex(0);
}
// ... rest of code ...
// We cast the value in i to a pointer width integer value, intptr_t
// to explicitly match the size of the void* we're smuggling it in
thread_handles[i] = (HANDLE)_beginthreadex(NULL, 0, &print_message, (void*)(intptr_t)i, 0, &thread_ID);
// ... rest of code ...
如果您所传递的只是一个小于指针宽度值,则可以将其值作为"指针"值本身走私。在这种情况下,您只需将其抬高到intptr_t
(与指针的宽度匹配的整数类型(,然后在提取上降低。
因为实际值是传递的,而不是指向它的指针,因此在调用_beginthreadex
之前制作副本,然后修改i
之后不会更改任何内容。
如果要传递的数据更大,那么您要么施加某种障碍(以确保在主线程再次触摸i
之前读取值(或使用动态内存使用(分配空间,在值,将指针传递给分配内存到线程,线程在释放空间之前提取值(。第三个选项是值的数组,每个线程一个(因此第一个线程接收&arr[i]
,其中i
为0
,下一个&arr[i]
用于i == 1
,等等(。
您可以传递值,而不是与此相似的指针。
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
void print(void *foo){
intptr_t bar = (intptr_t)foo;
printf("%" PRIdPTR "n",bar);
}
int main(void)
{
intptr_t i=1;
print((void*)i);
return 0;
}
您只需要小心,该功能确实将其视为值。在功能本身中,您必须确保施放的变量可以采用指针的大小。(这是通过使用intptr_t
完成的(
为了避免赛车通用,您可以使用静音者,但这在这里并不有用。
您可以以某种方式发出信号,说该值已在线程中读取并让循环等待直到那时,但这会使线程变得毫无用处。