Linux,C:在32位操作系统中,如何从大于4G的线程获取返回值?
我正在运行32位操作系统。 现在,我创建的线程将返回一个int值,该值可能大于Linux,C:在32位操作系统中,如何从大于4G的线程获取返回值?,c,linux,32-bit,C,Linux,32 Bit,我正在运行32位操作系统。 现在,我创建的线程将返回一个int值,该值可能大于4G。 如何通过pthread\u join()从我的main()函数接收此值? 在32位系统中,(void*)是4字节 #include<stdio.h> #include<pthread.h> #include<stdlib.h> void* thread_function(void) { uint64_t nbytes = 0; //assign value
4G
。
如何通过pthread\u join()
从我的main()
函数接收此值?
在32位
系统中,(void*)
是4字节
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
void* thread_function(void)
{
uint64_t nbytes = 0;
//assign values to nbytes, it could be larger than 4G.
return (void *)nbytes;
}
int main()
{
pthread_t thread_id;
uint64_t nbytes;
pthread_create (&thread_id, NULL, &thread_function, NULL);
pthread_join(thread_id,(void**)&nbytes);
}
#包括
#包括
#包括
void*thread_函数(void)
{
uint64字节=0;
//将值指定给nbytes,它可能大于4G。
返回(void*)n字节;
}
int main()
{
pthread_t thread_id;
uint64字节;
pthread_create(&thread_id,NULL,&thread_函数,NULL);
pthread_join(线程id,(void**)和n字节);
}
像这样:
void* thread_function(void *)
{
uint64_t nbytes = 0;
//assign values to nbytes, it could be larger than 4G.
void *retval = malloc (sizeof (nbytes));
memcpy (retval, &nbytes, sizeof (nbytes));
return retval;
}
int main()
{
pthread_t thread_id;
uint64_t nbytes;
pthread_create (&thread_id, NULL, &thread_function, NULL);
void *ret;
pthread_join(thread_id, &ret);
memcpy (nbytes, ret, sizeof (nbytes));
free (ret);
}
这是将值从一个线程传输到另一个线程的常见模式。发送线程分配内存、复制值并传递指针。接收线程获取指针,复制值并释放指针。David Schwartz的解决方案众所周知,但传递一个简单的整数有点太多<代码>malloc()非常昂贵,而且不一定是线程安全的(可能性很小,但现在有了所有嵌入的东西…) 了解OP前两位评论者的想法(WhozCraig和Eugene Sh.)
#包括
#包括
#包括
#包括
void*thread_函数(void*arg)
{
/*
无直接解引用
*arg=0xdeadbeefcafe;
将给出一个编译错误。对于GCC,它将是
threadargs.c:8:5:警告:取消引用“void*”指针[默认启用]
*/
uint64_t*nbytes=arg;
*n字节=0xdeadbeefcafe;
//您可以在此处返回一个简单的状态,例如错误
返回0;
}
int main()
{
pthread_t thread_id;
uint64字节;
pthread_create(&thread_id,NULL,&thread_函数,&nbytes);
pthread_join(thread_id,NULL);
#定义\u STDC\u格式\u宏
#包括
printf(“n字节=%”PRIx64“\n”,n字节);
返回0;
}
应该用另一种方法来做这项工作,也许对于这种用法来说是更好的方法
缺点:每个线程都希望填充自己的变量,因此它更适合固定的、少量的线程,否则您是从堆中分配的,并且没有赢得任何东西,恰恰相反:保留所有
malloc()/free()
会更复杂。David Schwartz的方法在这种情况下会更合适。为什么不将&nbytes
作为当前空参数发送到pthread\u create
,并通过函数中的地址简单地强制转换和设置值呢?首先,thread\u函数的类型是错误的。这应该需要争论。你猜怎么着?您可以使用这些参数来来回传递值。而且void*
返回类型实际上并不打算强制转换为非指针类型。thread\u函数
签名无效。作为一种替代方法(我想说是一种更安全的方法),它可以从接收线程获取一个指向预先分配的缓冲区的指针,然后填充它。将分配和释放代码放在同一级别是一种更好的做法。@EugeneSh。谢谢,修好了。这是一个非常标准的模式,因为即使接收线程不知道对象有多大,甚至线程的创建和连接在非常不同的位置,它也可以工作。我认为在这种情况下,将分配与线程的创建联系起来会更糟糕,因为它与结果的创建或使用位置没有逻辑关系。未知对象大小的用例非常有意义。如果您使用的是POSIX线程,那么malloc()
将是线程安全的。GlibC>=2.2(至少,我认为更早),但我被烧坏了太多,以至于不能给出“无论您多么确定,都要先检查”的提示。
#include <stdio.h>
#include <stdint.h>
#include <pthread.h>
#include <stdlib.h>
void *thread_function(void *arg)
{
/*
No direct dereferencing
*arg = 0xdeadbeefcafe;
would give a compile error. With GCC it would be
threadargs.c:8:5: warning: dereferencing ‘void *’ pointer [enabled by default]
*/
uint64_t *nbytes = arg;
*nbytes = 0xdeadbeefcafe;
// you can return a simple status here, for example an error
return 0;
}
int main()
{
pthread_t thread_id;
uint64_t nbytes;
pthread_create(&thread_id, NULL, &thread_function, &nbytes);
pthread_join(thread_id, NULL);
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
printf("nbytes = %" PRIx64 "\n", nbytes);
return 0;
}