Linux线程的内存布局

Linux线程的内存布局

在Linux的glibc中,通过pthread结构实现线程。由于线程和主进程是使用同一个虚拟地址空间,所以我们可以通过pmap -X 来比较线程运行前和运行后的虚拟地址空间变化。

// gcc main.c -lpthread && ./a.out
sem_t* sem;
void* thread_func(void *arg) {
    printf("wait thread\n");
    //int a[1024*4];
    sem_wait(sem);
    printf("finish thread\n");
    return NULL;
}
int main()
{
    pthread_t inc_x_thread;
    printf("Welcome to thread example:%d\n", getpid());
    getchar();
    printf("alloc sem device\n");
    sem = sem_open("malloctest_sem",O_RDWR | O_CREAT, 0755, 0);
    getchar();
    if( pthread_create(&inc_x_thread, NULL, thread_func, NULL)) {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }
    getchar();
    sem_post(sem);
    if(pthread_join(inc_x_thread, NULL)) {
        fprintf(stderr, "Error joining thread\n");
        return 2;
    }
    sem_close(sem);
    sem_unlink(sem);
    return 0;
}

当线程运行之后,我们可以看到,map了两个地址空间,一个是4KB空间,一个是8192KB=8MB。这两个地址空间都是在Memory Mapping Segment中。

这里写图片描述

  1. 8MB就是线程的栈,可以看到而实际只使用了8KB的空间。
  2. 4KB空间,刚好是一个页的大小,也就是mmap的最小单位。它的权限是无法读写执行,而且实际使用的空间为0,所以这块内存本身并不用来保存什么东西,只是为了保护下面的8MB的栈而已,避免/检测栈溢出的问题(栈是从高地址往低地址增长的,所以这个页要在栈下面)。

而存在多个子线程的时候,结果就是产生多对4KB和8MB的地址空间。

你可能感兴趣的:(linux)