【问题标题】:Query on return value of Thread Function in C查询C中线程函数的返回值
【发布时间】:2014-06-06 12:33:55
【问题描述】:

我正在使用下面的函数,它将使用 pthread_create() api 作为单独的线程启动。

static void * threadFunc(void *arg)
{
    char *s = (char *) arg;
    printf("%s", s);
    return (void *) strlen(s);
}

我的问题:

如果strlen(s) 的值为8(比如说), 在某些架构上,返回值存储在 %eax 中。这个值 8 对启动上述线程的 pthread_join() 调用中的主线程是否可见?

【问题讨论】:

  • 每个程序都有全局/堆栈/堆段。我猜返回值应该在全局段中,否则 pthread_join() 将无法访问它,如果返回值来自堆栈区域。
  • 函数返回值是如何实现的?
  • 要让pthread_join() 拉取值,请使用pthread_exit() 从(P)线程返回。
  • 一般来说,C 函数调用,据我所知,返回值存储在 accumulator(AC) 注册表中,调用者将读取该累加器。但我不知道 strlen() 是如何工作的
  • 每个问题一个问题。这不是留言板。

标签: c multithreading assembly pthreads


【解决方案1】:

1) 不。 strlen 在堆栈上(或根据架构在寄存器中)返回 size_t 值。 strlen 不会分配任何内存来保存其结果。

2) 将其返回值转换为 (void *) 是一个非常糟糕的主意。您所做的只是获取一个 size_t 值(在您的示例中为 8)并告诉编译器假装它是指向内存区域的指针。

这些都不是真正的 pthread 特定的,只是普通的 C。如果你想按预期使用 void *,想法是你返回一个指向你分配的数据结构的指针,然后调用者需要释放它.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void *testFunc( char * );


void *testFunc( char *s ){
  size_t *returnMemory = malloc( sizeof( size_t ) );
  size_t len = strlen(s);
  *returnMemory = len;
  return returnMemory;
}

int main( int argc, char *argv[] ){
  void *valPtr = testFunc( "Test String" );
  size_t *sizePtr = (size_t *)valPtr;

  printf( "%p => %zu\n", valPtr, *sizePtr );
  exit(0);
}

【讨论】:

  • 即使我只返回 'strlen(s)' 实现内部强制转换为 void * 否则 pthread_join() 不能接受返回值。
  • 是的。该函数被定义为返回一个 void *。关键是,如果您将非指针值偷偷带入其中,您会发现自己在某个时候被破坏了。目的是返回一个指向数据结构的指针,然后父线程可以安全地使用该数据结构。除了在 void *arg 中传递 char * 之外,您还可以为两者传递一个带有空格的结构。
  • 这里 returnMemory 将其值传递给 valPtr,这是堆地址,但如果我在线程上启动 testFunc(),则 pthread_join(t,void**) 的第二个参数将存储 &returnMemory,即堆栈区域。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-12
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 2015-06-21
相关资源
最近更新 更多