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

kh212irz  于 2023-10-16  发布在  其他
关注(0)|答案(9)|浏览(101)

我需要传递多个参数给一个函数,我想在一个单独的线程上调用。我读过这样做的典型方法是定义一个结构体,向函数传递一个指向该结构体的指针,并将其解引用为参数。但是,我无法让它工作:

#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

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

ztyzrc3y

ztyzrc3y1#

因为你说
struct arg_struct *args = (struct arg_struct *)args;
而不是
struct arg_struct *args = arguments;

sf6xfgos

sf6xfgos2#

使用

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

代替

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

xe55xuns3#

main()有自己的线程和堆栈变量。要么在堆中为'args'分配内存,要么使其全局化:

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

//declares args as global out of main()

然后当然将引用从args->arg1更改为args.arg1等。

a0zr77ik

a0zr77ik4#

用途:

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

并像这样传递参数:

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

别忘了free args!;)

tjvv9vkg

tjvv9vkg5#

我和最初的海报有同样的问题,迈克尔。
然而,我试图申请的答案提交的原始代码没有成功
经过一些尝试和错误,这里是我的代码版本,工作(或至少为我工作!)。如果你仔细看,你会注意到它与早期发布的解决方案不同。

#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 */
}
dm7nw8vv

dm7nw8vv6#

在此代码的线程创建中,传递函数指针的地址。原始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似乎会导致不确定的行为。添加this意味着传递的是布尔值而不是引用。
AkashAgrawal的回答也是解决这段代码问题的一部分。

jm81lzqq

jm81lzqq7#

print_the_arguments的args是参数,所以你应该使用:用途:

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

u4vypkhs8#

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

-->这个赋值是错误的,我的意思是变量参数应该在这个上下文中使用。干杯!

uajslkp6

uajslkp69#

由于asking the same question but for C++ is considered a duplicate,我也可以提供C++代码作为答案。

//  hello-2args.cpp
// https://stackoverflow.com/questions/1352749
#include <iostream>
#include <omp.h>
#include <pthread.h>
using namespace std;

typedef struct thread_arguments {
  int thrnr;
  char *msg;
} thargs_t;

void *print_hello(void *thrgs) {
  cout << ((thargs_t*)thrgs)->msg << ((thargs_t*)thrgs)->thrnr << "\n";
  pthread_exit(NULL);
}

int main(int argc, char *argv[]) {
  cout << " Hello C++!\n";
  const int NR_THRDS = omp_get_max_threads();
  pthread_t threads[NR_THRDS];
  thargs_t thrgs[NR_THRDS];
  for(int t=0;t<NR_THRDS;t++) {
    thrgs[t].thrnr = t;
    thrgs[t].msg = (char*)"Hello World. - It's me! ... thread #";
    cout << "In main: creating thread " << t << "\n";
    pthread_create(&threads[t], NULL, print_hello, &thrgs[t]);
  }
  for(int t=0;t<NR_THRDS;t++) {
    pthread_join(threads[t], NULL);
  }
  cout << "After join: I am always last. Byebye!\n";
  return EXIT_SUCCESS;
}

使用以下选项之一编译并运行:

g++ -fopenmp -pthread hello-2args.cpp && ./a.out # Linux
g++ -fopenmp -pthread hello-2args.cpp && ./a.exe # MSYS2, Windows

相关问题