【问题标题】:About pthread_create() and pthread_join()关于 pthread_create() 和 pthread_join()
【发布时间】:2015-10-16 18:50:59
【问题描述】:

我刚开始研究pthread 的跨平台。但我真的对用于pthread_create()pthread_join() 的变量类型感到困惑。请看下面的代码。

// This is just simple code for test, so don't take this variable seriously!
int result;
void* myThreadFunc(void* arg) {
    result = *(int*)arg;

    // Why not &result, but result???
    return (void*)result;
}

int main() {
    pthread_t myThread;
    int argForThread = 10;
    int threadResult = 0;

    pthread_create(&myThread, NULL, myThreadFunc, (void*)&argForThread);

    // Why (void**), but not (void*)?
    pthread_join(myThread, (void**)&threadResult);

    return 0;
}

正如我在 cmets 中所写,我不了解那些指针,这对我来说没有意义。

对于第一个,为什么我必须将值类型放在一个指针类型?

对于第二个,为什么我只需要一个局部变量的地址进行双指针转换?

【问题讨论】:

  • 请一次一个问题。
  • 但我觉得说到底还是一个问题,这个问题全是C++中的POINTER。实际上与函数无关。
  • 你想要跨平台的代码?使用 C++'std::thread!
  • @UlrichEckhardt 感谢您提供信息。总有一天会很有帮助,但这次,我应该坚持 C :)
  • 你的问题是用 C++ 标记的!那是一种不同的语言,你不应该使用 is 作为标签。

标签: c linux multithreading pointers pthreads


【解决方案1】:

您的函数myThreadFunc 将指向内存中任何位置的指针作为其参数。我们不知道那个位置的类型,所以它是一个void *,你可以把它转换成你想要的任何类型。您将它转换为指向整数 argForThread 的指针,这将是 &argForThread,然后您取消它的引用,产生 10 的值。

您的退货声明不正确。您正在返回 &result 但变量在堆栈上。一旦函数返回,变量就不再存在。如果要将计算值返回给调用者,则需要为此分配内存,然后返回已分配内存的地址。然后调用者将取消引用它收到的地址,获取值,最后释放内存。 (新手程序员可能会返回静态值的地址或堆栈上的某些东西,但这不是线程安全的。)

当您返回(void *)result 时,您将返回值result,就好像它是指向内存中某处的指针一样。该内存位置几乎可以肯定是无效的。但是,这并不重要,因为您不会取消引用返回的位置。 (我应该注意,在具有 32 位整数和 64 位指针的系统上,您会遇到不可预知的行为。)

线程结果是void **,因为您传递了一个指针,该指针将被变异为指向myThreadFunc 返回的位置。因此,在您的示例中,threadResult 将以值 result * result 结束,因此它将指向无效的内存位置。在你的例子中没关系,因为threadResult 是一个整数,而不是一个指针。

【讨论】:

  • 感谢您的友好解释并指出我在退货声明中的错误,我现在进行了编辑。但是还是不明白为什么我不能只放(void*)&result,而是(void*)resultvoid* 是指针类型,result 本身就是一个值。
  • result 是一个堆栈变量,在函数返回时不再存在。如果您返回&result,您将返回一个指向内存中某个位置的指针,该位置可能很快就会非常不同。
  • 您想返回result,而不是它在即将不复存在的堆栈上的无意义地址。
  • 我编辑了变量result 是一个全局变量。我的意思是int a = 123; void* pa = (void*)a; 没有意义,因为这两种类型是不同的。但是int a = 123; void* pa = (void*)&a; 是有道理的。
  • 如果你想返回(void *)&a,那很好,但是你需要将一个指针的地址传递给pthread_join,你需要取消引用它来获得你的值。
猜你喜欢
  • 1970-01-01
  • 2011-09-22
  • 1970-01-01
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
相关资源
最近更新 更多