访问linux线程(pthreads)的本地堆栈 [英] Access local stack of linux threads (pthreads)

查看:113
本文介绍了访问linux线程(pthreads)的本地堆栈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我当前正在实现一个使用多线程但对总内存消耗有要求的应用程序.我想要一个执行I/O的主线程和几个执行计算的工作人员.

I'm currently implementing an application that makes use of multithreading but has requirements on the total memory consumption. I'd like to have a master thread doing I/O and several workers doing computations.

目前,我在主堆栈上有几个数据结构,这些数据结构可供工作人员访问.我使用OpenMP进行工作分配.由于master/worker模式不适用于OpenMP,因此我想使用pthreads进行多线程处理.

Currently I'm having several datastructures on the masters stack that are accessed by the workers. I use OpenMP for work distribution. As the master/worker pattern doesn't work well with OpenMP I'd like to use pthreads for multithreading.

我知道每个线程都维护一个本地堆栈,但是在创建线程时该堆栈究竟会发生什么?

I know that each thread maintains a local stack, but what exactly will happening to the stack on thread creation?

工作人员是否可以访问位于主机堆栈上的数据结构,还是应该将其移至堆? 我还想避免重复数据,但是不知道新线程是否会创建母版堆栈的本地副本.

Are datastructures that lie on the master's stack accessible by the workers or should I move them to the heap? I'd also like to avoid duplication of data but don't know if new threads will create a local copy of the masters stack.

自己找到答案...

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

After reading into the details of the clone() system call that is used by pthreads I realized that all threads share the complete virtual memory. This means that although threads use their own stack, the memory regions that are used for each stack are still shared.

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

I wrote some code to verify that behaviour:

#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",因此线程成功地操纵了其父线程的堆栈.

As output is "200" the threads manipulated the stack of their parent thread successfully.

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

I think most ressources on the internet dont't express this fact correctly. Threads do share the stack in the sense of shared memory, but the stackpointer of each thread is private. For each thread a part of the shared memory is assigned as local stack.

这也意味着父线程在堆栈上是否具有大数据结构无关紧要,因为从不为线程复制内存.

This also means that it doesn't matter if the parent thread has large data structures on the stack, as memory is never duplicated for threading.

推荐答案

是的,正如您所解释的,您可以共享堆栈.但是,一般而言,除了少数特殊情况外,您不应该这样做.您的示例程序有数据争用,因此仅凭运气就只能输出200(也许是因为您的操作系统实际上并未安排子进程同时运行.)

Yes, you can share your stacks, as you explain. In general, however, you should not, except in a few special circumstances. Your example program has data races, and so the output will only be 200 through pure luck (perhaps because your operating system doesn't actually schedule the children to run simultaneously.)

共享堆栈很有意义的一种特殊情况是,父级创建一些有趣的数据结构,然后将其传递给其子级,后者访问该数据结构为只读.

One special circumstance where it does make sense to share the stack is when the parent creates some interesting data structure, and then passes it to its children, who access the data structure read only.

除了数据争用之外,还有另一件事可能是在堆栈而不是堆上共享.父级可以从创建子线程的过程中返回,因此堆栈数据在子线程的生存期内可能不会保持有效.因此,仅当pthread_create()调用和匹配的pthread_join()调用在同一范围内时才共享堆栈数据(如您的示例中一样).

Other than data races, here's another thing that can go wrong with sharing on the stack instead of the heap. The parent can return from the procedure where it created the child threads, so the stack data may not stay valid for the lifetime of the child thread. So you should only share stack data if the pthread_create() call and the matching pthread_join() call are in the same scope (as they are in your example.)

这篇关于访问linux线程(pthreads)的本地堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆