我需要将多个参数传递给我想在单独线程上调用的函数。我已经读到,执行此操作的典型方法是定义一个结构体,向函数传递一个指向该结构体的指针,然后取消对它的参数的引用。但是,我无法让它工作:
#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
有人知道我做错了什么吗?
因为你说
struct arg_struct *args = (struct arg_struct *)args;
而不是
struct arg_struct *args = arguments;
使用
struct arg_struct *args = (struct arg_struct *)arguments;
代替
struct arg_struct *args = (struct arg_struct *)args;
main()
有自己的线程和堆栈变量。为堆中的“args”分配内存或将其设置为全局:
struct arg_struct {
int arg1;
int arg2;
}args;
//declares args as global out of main()
然后当然将参考文献从
args->arg1
更改为args.arg1
等..
用途:
struct arg_struct *args = malloc(sizeof(struct arg_struct));
并像这样传递这个参数:
pthread_create(&tr, NULL, print_the_arguments, (void *)args);
不要忘记免费参数! ;)
我和原发帖者迈克尔有同样的问题。
但是我尝试应用为原始代码提交的答案,但没有成功
经过一番尝试和错误,这是我的有效代码版本(或者至少对我有用!)。如果你仔细观察,你会发现它与之前发布的解决方案不同。
#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 */
}
在此代码的线程创建中,正在传递函数指针的地址。 原本的
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 的回答也是此代码问题解决方案的一部分。
print_the_arguments 的 args 是参数,所以你应该使用:
struct arg_struct *args = (struct arg_struct *)arguments.
struct arg_struct *args = (struct arg_struct *)args;
--> 这个赋值是错误的,我的意思是变量参数应该在这种情况下使用。 干杯!!!
因为问同样的问题但对于 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