由pthread_create()调用的函数有多个参数?


93

我需要将多个参数传递给要在单独线程上调用的函数。我已经读到,执行此操作的典型方法是定义一个struct,向该函数传递一个指向该struct的指针,然后将其取消引用以用作参数。但是,我无法使它正常工作:

#include <stdio.h>
#include <pthread.h>

struct arg_struct {
    int arg1;
    int arg2;
};

void *print_the_arguments(void *arguments)
{
    struct arg_struct *args = (struct arg_struct *)args;
    printf("%d\n", args -> arg1);
    printf("%d\n", args -> arg2);
    pthread_exit(NULL);
    return NULL;
}

int main()
{
    pthread_t some_thread;
    struct arg_struct args;
    args.arg1 = 5;
    args.arg2 = 7;

    if (pthread_create(&some_thread, NULL, &print_the_arguments, (void *)&args) != 0) {
        printf("Uh-oh!\n");
        return -1;
    }

    return pthread_join(some_thread, NULL); /* Wait until thread is finished */
}

输出应为:

5
7

但是当我运行它时,我实际上得到了:

141921115
-1947974263

有人知道我在做什么错吗?


2
尝试在堆上分配它?
卡森·迈尔斯,2009年

1
@Carson为什么要有所作为?
sigjuice

5
您的结构至少应与线程寿命相同。如果要创建线程并从调用pthread_create()的函数返回,则分配在堆栈上的结构可能会被其他数据覆盖,并可能导致线程函数出现问题。在此示例中,这不是问题,因为创建线程在返回之前会等待工作线程完成。
准将Jaeger,2009年

@Commodore Jaeger哦!谢谢,这就是我和其他正在工作的人所遇到的问题。正如Carson所说,我通过使用malloc()在堆上分配它来修复它。现在,这变得更加有意义。
迈克尔

Answers:


77

因为你说

struct arg_struct *args = (struct arg_struct *)args;

代替

struct arg_struct *args = arguments;


4
@sigjuice,它对我不起作用。我看到编译错误:从“ void *”到“ arg_struct *”的无效转换。
Neshta 2014年


4

main()有它自己的线程和堆栈变量。为堆中的“ args”分配内存或使其成为全局内存:

struct arg_struct {
    int arg1;
    int arg2;
}args;

//declares args as global out of main()

然后,当然,改变从引用args->arg1args.arg1等。


2

用:

struct arg_struct *args = malloc(sizeof(struct arg_struct));

并像下面这样传递参数:

pthread_create(&tr, NULL, print_the_arguments, (void *)args);

不要忘记免费的参数!;)


1

print_the_arguments的参数是参数,因此您应该使用:

struct arg_struct *args = (struct arg_struct *)arguments. 

1
struct arg_struct *args = (struct arg_struct *)args;

->这种分配是错误的,我的意思是在这种情况下应该使用变量参数。干杯!!!


1

在此代码的线程创建中,将传递函数指针的地址。原本的 pthread_create(&some_thread, NULL, &print_the_arguments, (void *)&args) != 0

它应显示为 pthread_create(&some_thread, NULL, print_the_arguments, (void *) &args)

记住的一个好方法是该函数的所有参数都应为地址。

some_thread是静态声明的,因此可以使用正确发送地址&

我将创建一个pthread_attr_t变量,然后pthread_attr_init()在其上使用并传递该变量的地址。但是,传递NULL指针也是有效的。

&功能标签的前面是什么在这里导致问题。所使用的标签已经是void*功能的标签,因此仅需要标签。

!= 0用最后一个论点说似乎会引起不确定的行为。加上这个意味着将传递一个布尔值而不是一个引用。

Akash Agrawal的答案也是该代码问题解决方案的一部分。


1

我和原始海报的迈克尔有同样的问题。

但是我试图应用为原始代码提交的答案,但没有成功

经过反复试验,这是我可以使用的代码版本(或至少对我有用!)。如果仔细观察,您会注意到它与先前发布的解决方案不同。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

struct arg_struct
{
   int arg1;
   int arg2;
} *args;

void *print_the_arguments(void *arguments)
{
   struct arg_struct *args = arguments;
   printf("Thread\n");
   printf("%d\n", args->arg1);
   printf("%d\n", args->arg2);
   pthread_exit(NULL);
   return NULL;
}

int main()
{
   pthread_t some_thread;
   args = malloc(sizeof(struct arg_struct) * 1);

   args->arg1 = 5;
   args->arg2 = 7;

   printf("Before\n");
   printf("%d\n", args->arg1);
   printf("%d\n", args->arg2);
   printf("\n");


   if (pthread_create(&some_thread, NULL, &print_the_arguments, args) != 0)
   {
      printf("Uh-oh!\n");
      return -1;
   }

   return pthread_join(some_thread, NULL); /* Wait until thread is finished */
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.