如何将 int 作为 "void *" 传递给线程启动函数?
How to pass an int as "void *" to thread start function?
我最初为我的斐波那契变量数组设置了一个全局变量,但后来发现这是不允许的。我需要进行基本的多线程处理并处理竞争条件,但我无法在 pthread create 中将一个 int 作为 void 参数。我试过使用常量指针但没有运气。出于某种奇怪的原因,void* 通过了第一个布尔测试,但没有通过 else,如果:
$ gcc -o fibonacci fibonacci.c
fibonacci.c:22:16: warning: comparison between pointer and integer ('void *' and 'int')
else if (arg == 1)
~~~ ^ ~
1 warning generated.
我的代码很乱,我真的很困惑,因为我重写了很多次。如果我将线程 运行 函数中的所有参数都转换为整数,我会得到一个分段错误 11,这是有道理的。所有通过地址传递 i 索引并取消引用它的尝试都失败了,因为它是一个 void 并且不能用作 int。你能推荐别的吗?
#include<stdio.h> //for printf
#include<stdlib.h> //for malloc
#include<pthread.h> //for threading
#define SIZE 25 //number of fibonaccis to be computed
int *fibResults; //array to store fibonacci results
void *run(void *arg) //executes and exits each thread
{
if (arg == 0)
{
fibResults[(int)arg] = 0;
printf("The fibonacci of %d= %d\n", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else if (arg == 1)
{
fibResults[(int)arg] = 1;
printf("The fibonacci of %d= %d\n", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else
{
fibResults[(int)arg] = fibResults[(int)arg -1] + fibResults[(int)arg -2];
printf("The fibonacci of %d= %d\n", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
}
//main function that drives the program.
int main()
{
pthread_attr_t a;
fibResults = (int*)malloc (SIZE * sizeof(int));
pthread_attr_init(&a);
for (int i = 0; i < SIZE; i++)
{
pthread_t thread;
pthread_create(&thread, &a, run,(void*) &i);
printf("Thread[%d] created\t", i);
fflush(stdout);
pthread_join(thread, NULL);
printf("Thread[%d] joined & exited\t", i);
}
return 0;
}
@efuddy。而不是 (int)arg
你应该使用 (int *)arg
来正确地转换 **void pointer* void *arg
在run()
函数中你应该做的:
void *run(void *ptrarg) //executes and exits each thread
{
int arg = *((int *)ptrarg);
if (arg == 0)
....
....
并且在 run()
的其余部分,您不需要投射 arg
。将 (int)arg
替换为 arg
.
编辑:
创建线程时将参数传递给 fun()
的方式可能会导致 race condition,因为所有线程都将使用相同的指针。检查@Jonathan 的回答以避免此问题。
您不需要在对 pthread_create()
的调用中进行强制转换 — 到 void *
的转换是自动的。
在线程函数中,可以使用
int i = *(int *)arg;
但是,您现在遇到了同步问题;所有线程都使用相同的(指向相同的)整数变量,并且由于调度问题,您无法预测它们将看到哪个值。每线程数据需要 'per thread'.
因此,有多种解决方法。在这种情况下,我可能会使用
#include <stdint.h>
并在 main()
中:
pthread_create(&thread, &a, run, (void*)(uintptr_t)i);
然后在线程函数中:
int i = (uintptr_t)arg;
现在演员表——甚至是双重演员表——是必要的。强制转换为 uintptr_t
可确保整数值足够大以容纳指针;需要转换为 void *
,因为没有从任何整数类型到 void *
的隐式转换。这确保每个线程函数调用都有不同的值。共享指向 int
的指针意味着一切都不受控制。
我最初为我的斐波那契变量数组设置了一个全局变量,但后来发现这是不允许的。我需要进行基本的多线程处理并处理竞争条件,但我无法在 pthread create 中将一个 int 作为 void 参数。我试过使用常量指针但没有运气。出于某种奇怪的原因,void* 通过了第一个布尔测试,但没有通过 else,如果:
$ gcc -o fibonacci fibonacci.c
fibonacci.c:22:16: warning: comparison between pointer and integer ('void *' and 'int')
else if (arg == 1)
~~~ ^ ~
1 warning generated.
我的代码很乱,我真的很困惑,因为我重写了很多次。如果我将线程 运行 函数中的所有参数都转换为整数,我会得到一个分段错误 11,这是有道理的。所有通过地址传递 i 索引并取消引用它的尝试都失败了,因为它是一个 void 并且不能用作 int。你能推荐别的吗?
#include<stdio.h> //for printf
#include<stdlib.h> //for malloc
#include<pthread.h> //for threading
#define SIZE 25 //number of fibonaccis to be computed
int *fibResults; //array to store fibonacci results
void *run(void *arg) //executes and exits each thread
{
if (arg == 0)
{
fibResults[(int)arg] = 0;
printf("The fibonacci of %d= %d\n", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else if (arg == 1)
{
fibResults[(int)arg] = 1;
printf("The fibonacci of %d= %d\n", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else
{
fibResults[(int)arg] = fibResults[(int)arg -1] + fibResults[(int)arg -2];
printf("The fibonacci of %d= %d\n", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
}
//main function that drives the program.
int main()
{
pthread_attr_t a;
fibResults = (int*)malloc (SIZE * sizeof(int));
pthread_attr_init(&a);
for (int i = 0; i < SIZE; i++)
{
pthread_t thread;
pthread_create(&thread, &a, run,(void*) &i);
printf("Thread[%d] created\t", i);
fflush(stdout);
pthread_join(thread, NULL);
printf("Thread[%d] joined & exited\t", i);
}
return 0;
}
@efuddy。而不是 (int)arg
你应该使用 (int *)arg
来正确地转换 **void pointer* void *arg
在run()
函数中你应该做的:
void *run(void *ptrarg) //executes and exits each thread
{
int arg = *((int *)ptrarg);
if (arg == 0)
....
....
并且在 run()
的其余部分,您不需要投射 arg
。将 (int)arg
替换为 arg
.
编辑:
创建线程时将参数传递给 fun()
的方式可能会导致 race condition,因为所有线程都将使用相同的指针。检查@Jonathan 的回答以避免此问题。
您不需要在对 pthread_create()
的调用中进行强制转换 — 到 void *
的转换是自动的。
在线程函数中,可以使用
int i = *(int *)arg;
但是,您现在遇到了同步问题;所有线程都使用相同的(指向相同的)整数变量,并且由于调度问题,您无法预测它们将看到哪个值。每线程数据需要 'per thread'.
因此,有多种解决方法。在这种情况下,我可能会使用
#include <stdint.h>
并在 main()
中:
pthread_create(&thread, &a, run, (void*)(uintptr_t)i);
然后在线程函数中:
int i = (uintptr_t)arg;
现在演员表——甚至是双重演员表——是必要的。强制转换为 uintptr_t
可确保整数值足够大以容纳指针;需要转换为 void *
,因为没有从任何整数类型到 void *
的隐式转换。这确保每个线程函数调用都有不同的值。共享指向 int
的指针意味着一切都不受控制。