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

问题描述 投票:0回答:9

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

#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

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

c pthreads
9个回答
97
投票

因为你说

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

而不是

struct arg_struct *args = arguments;


27
投票

使用

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

代替

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

6
投票

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

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

//declares args as global out of main()

然后当然将参考文献从

args->arg1
更改为
args.arg1
等..


3
投票

用途:

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

并像这样传递这个参数:

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

不要忘记免费参数! ;)


3
投票

我和原发帖者迈克尔有同样的问题。

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

经过一番尝试和错误,这是我的有效代码版本(或者至少对我有用!)。如果你仔细观察,你会发现它与之前发布的解决方案不同。

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

2
投票

在此代码的线程创建中,正在传递函数指针的地址。 原本的

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
投票

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

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

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

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


0
投票

因为问同样的问题但对于 C++ 被认为是重复的我不妨提供 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
© www.soinside.com 2019 - 2024. All rights reserved.