gpt4 book ai didi

c++ - 访问本地 linux 线程栈 (pthreads)

转载 作者:IT王子 更新时间:2023-10-29 01:23:12 27 4
gpt4 key购买 nike

我目前正在实现一个使用多线程但对总内存消耗有要求的应用程序。我想要一个主线程做 I/O 和几个 worker 做计算。

目前,我在主堆栈上有几个数据结构可供工作人员访问。我使用 OpenMP 进行工作分配。由于 master/worker 模式不能很好地与 OpenMP 配合使用,我想使用 pthreads 进行多线程处理。

我知道每个线程都维护一个本地栈,但是创建线程时栈到底会发生什么?

位于 master 堆栈上的数据结构是否可以被 worker 访问,或者我应该将它们移动到堆中吗?我还想避免数据重复,但不知道新线程是否会创建主堆栈的本地拷贝。


编辑:自己找到了答案......

在阅读了 pthreads 使用的 clone() 系统调用的细节后,我意识到所有线程共享完整的虚拟内存。这意味着尽管线程使用它们自己的堆栈,但用于每个堆栈的内存区域仍然是共享的。

我写了一些代码来验证该行为:

#include <stdio.h>
#include <pthread.h>

void* increment(void* value) {
int* val = (int*) value;
for(int i = 0; i < 100; i++) {
++(*val);
}
return 0;
}

int main(int argc, char** argv) {

int stackvar = 0;

pthread_t thread1, thread2;
int iret1, iret2;

iret1 = pthread_create( &thread1, NULL, increment, (void*) &stackvar );
iret2 = pthread_create( &thread2, NULL, increment, (void*) &stackvar );

pthread_join( thread1, NULL );
pthread_join( thread2, NULL );

printf("%i\n", stackvar);

return 0;
}

由于输出为“200”,线程成功地操作了它们父线程的堆栈。

我认为互联网上的大多数资源都没有正确表达这一事实。线程确实在共享内存的意义上共享堆栈,但每个线程的堆栈指针都是私有(private)的。对于每个线程,共享 内存的一部分被分配为本地堆栈。

这也意味着父线程在堆栈上是否有大型数据结构并不重要,因为内存永远不会为线程复制。

最佳答案

是的,正如您所解释的,您可以分享您的堆栈。但是,一般情况下,您不应该这样做,除非在一些特殊情况下。您的示例程序存在数据竞争,因此纯属运气输出仅为 200(可能是因为您的操作系统实际上并未安排子程序同时运行。)

共享堆栈确实有​​意义的一种特殊情况是,当父级创建一些有趣的数据结构,然后将其传递给其子级时,子级访问数据结构只读。 p>

除了数据竞争之外,在堆栈而不是堆上共享还有另一件事可能会出错。父线程可以从创建子线程的过程中返回,因此堆栈数据可能不会在子线程的生命周期内保持有效。因此,如果 pthread_create() 调用和匹配的 pthread_join() 调用在同一范围内(就像它们在您的示例中一样),您应该只共享堆栈数据。

关于c++ - 访问本地 linux 线程栈 (pthreads),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18880016/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com