Linux,C:在32位操作系统中,如何从大于4G的线程获取返回值?

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

我正在运行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 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;
}