我需要将多个参数传递给我想在单独的线程上调用的函数。我read这样做的典型方法是定义一个结构,向该函数传递指向该结构的指针,并为参数取消引用它。但是,我无法让这个工作:
#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
任何人都知道我做错了什么?
答案 0 :(得分:65)
因为你说
struct arg_struct *args = (struct arg_struct *)args;
而不是
struct arg_struct *args = arguments;
答案 1 :(得分:16)
使用
struct arg_struct *args = (struct arg_struct *)arguments;
取代
struct arg_struct *args = (struct arg_struct *)args;
答案 2 :(得分:4)
main()
拥有自己的线程和堆栈变量。要么为堆中的'args'分配内存,要么将其设为全局:
struct arg_struct {
int arg1;
int arg2;
}args;
//declares args as global out of main()
然后当然会将引用从args->arg1
更改为args.arg1
等等。
答案 3 :(得分:2)
使用:
struct arg_struct *args = malloc(sizeof(struct arg_struct));
并传递这样的论点:
pthread_create(&tr, NULL, print_the_arguments, (void *)args);
别忘了免费的args! ;)
答案 4 :(得分:1)
struct arg_struct *args = (struct arg_struct *)args;
->这种分配是错误的,我的意思是在这种情况下应该使用变量参数。 干杯!!!
答案 5 :(得分: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的答案也是该代码问题解决方案的一部分。
答案 6 :(得分: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 */
}
答案 7 :(得分:0)
print_the_arguments的参数是参数,因此您应该使用:
struct arg_struct *args = (struct arg_struct *)arguments.
答案 8 :(得分:0)
自Solaris sigaction()
起,我不妨提供C ++代码作为答案。
volatile sig_atomic_t running;
void handler( int sig );
{
running = 0;
}
...
struct sigaction sa;
memset( &sa, 0, sizeof( sa ) );
sa.sa_handler = handler;
sigaction( SIGALRM, &sa, NULL );
while(running)
{
// 10-sec timeout
alarm( 10 );
errno = 0;
ssize_t result = msgrcv( msqid, &req_msg, sizeof(req_msg.mtext), 0, 0 );
// save errno as alarm() can munge it
int saved_errno = errno;
// clear alarm if it hasn't fired yet
alarm( 0 );
if ( result == ( ssize_t ) -1 )
{
// if the call failed or no longer running
// break the loop
if ( ( saved_errno != EINTR ) || !running )
{
break;
}
// the call was interrupted by a signal
continue
}
...
}
使用以下方法之一进行编译和运行:
insert into destinationsever.destinationdatabase.dbo.destinationtable
select * from sourcesever.sourcedatabase.dbo.sourcetable