考虑这个简单的代码:
void* threadFunction(void* arg) {
int argument=(int)arg;
printf("%d recieved\n", argument);
return NULL;
}
int main(int argv, char* argc[]) {
int error;
int i=0;
pthread_t thread;
int argument_to_thread=0;
if ((error=pthread_create(&thread, NULL, threadFunction, (void*)argument_to_thread))!=0) {
printf("Can't create thread: [%s]\n", strerror(error));
return 1;
}
pthread_join(thread, NULL);
return 0;
}
这很有效,但有两件事让我烦恼。
首先,我想向threadFunction()发送多个参数。
当然,我可以传递一个指向数组的指针,但是如果我想传递两个不同类型的参数呢? (比如int
和char*
)怎么办?
在这里困扰我的第二件事是我在编译上面时得到的警告......
test2.c: In function ‘threadFunction’:
test2.c:8:15: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
int argument=(int)arg;
^
test2.c: In function ‘main’:
test2.c:24:59: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
if ((error=pthread_create(&thread, NULL, threadFunction, (void*)argument_to_thread))!=0) {
^
现在,我可以通过这样做来消除这种情况:
if ((error=pthread_create(&thread, NULL, threadFunction, (void*)&argument_to_thread))!=0) {
printf("Can't create thread: [%s]\n", strerror(error));
return 1;
}
但是,让我们说我不想通过引用传递它...有没有办法传递,说...一个int,按值作为参数,而编译器没有警告我? / p>
答案 0 :(得分:2)
有两种方法可以做到这一点:
使用malloc
获取参数结构的存储空间,并让新线程负责在参数完成后调用free
。 (注意:如果pthread_create
失败,则需要在失败路径中free
此存储。)
使用信号量(或其他同步,但信号量是目前最轻的)。
以下是后者的一个例子:
struct args {
int a;
char *b;
sem_t sem;
};
void *thread_func(void *p)
{
struct args *args = p;
int a = args->a;
char *b = args->b;
sem_post(args->sem);
...
}
/* in caller */
struct args args;
args.a = ...;
args.b = ...;
sem_init(&args.sem, 0, 0);
pthread_create(&tid, 0, thread_func, &args);
sem_wait(&args.sem);
...
答案 1 :(得分:2)
如果你想通过值传递但警告消失,请使用此演员:
(void *)(uintptr_t)argument_to_thread
通过uintptr_t
的中间演员避免了尺寸不匹配。同样,在回退时,请使用:
(int)(uintptr_t)voidptr_arg
如评论中所述,不一定建议使用上述方法,因为它依赖于实现定义的行为。假设您不需要全范围的int
但只需要很小的范围,那么完全可移植的方法是:
static const char int_to_ptr_trick[MAXVAL];
void *ptr = int_to_ptr_trick + int_val;
int int_val = (char *)ptr - int_to_ptr_trick;
答案 2 :(得分:1)
传递整数的地址。
int argument = 123 ;
pthread_create(&thread, NULL, threadFunction, &argument)) ;
并在线程函数
中 int argument= *(int*)arg ;
如果您希望传递多个参数,可以使用与上述示例相同的方法创建包含值的结构。
如果函数的参数为void *,则不能按值传递整数。您必须提供变量或结构的地址。