进程栈与线程栈

本文介绍了虚拟内存的概念,以及在Linux环境下进程和线程栈的运作原理。讨论了c程序的存储空间布局,指出栈从高地址向低地址增长。当线程数过多或栈空间需求超过虚拟地址空间时,可通过调整线程栈大小来避免问题。并提供了查看和修改线程栈大小的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是虚拟内存?

什么是进程栈?

什么是线程栈?

这几个知识点是有关联的。


1.虚拟内存

虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存(例如RAM)的使用也更有效率。(参考维基百科:虚拟内存)

《深入了解计算机系统》第2版第9章虚拟存储器也有详细讲解


2.在虚拟内存的基础上,看c程序的存储空间分布


引用《unix环境高级编程》第2版

7.6节c程序的存储空间布局:对于x86处理器上的Linux,正文段从0x08048000单元开始,栈底则在0xC0000000之下开始(在这种特定结构中,栈从高地址向低地址方向增长)。堆顶和栈底之间未用的虚地址空间很大。

12.3节线程属性:对进程来说,虚拟地址空间大小的固定的,如果应用程序使用了太多的线程,致使线程栈的累计大小超过了可用的虚拟地址空间,这时就需要减少线程的默认栈大小


ps:栈从高地址向低地址方向增长,这很好的解析了为什么先定义的局部变量地址大,后定义的局部变量地址小


3.如何查看线程栈大小,重复,是线程栈



可以看到这个测试机器的默认stack size是8MB,然后做了些简单的测试


下面是一个简单的单线程程序 over.cpp

---------------------------------

#include <stdio.h>
struct test{
    char arr[1024];
};

int main(){
    struct test a[8192];
    int x = 1;
}

-----------------------------------

g++ over.cpp,编译后运行,程序会在分配变量x时报Segmentation fault,程序分配总空间大于8MB



下面是一个简单的双线程程序stack.cpp

---------------------------------

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

struct test{
    char arr[1024];
};

void *thread_function(void *threadid)
{
   printf("pthread_create success\n");
   struct test a[8000];
   int x = 1;
   sleep(512);
}

int main(){
    struct test a[8000];
    int x = 1;
    pthread_t a_thread;
    pthread_create(&a_thread, NULL, thread_function, (void *)&x);
    sleep(512);
}

---------------------------------

g++ stack.cpp -lpthread,编译后运行,程序正常运行,程序分配总空间大于8MB



4.如果修改线程栈限制

1.通过ulimit命令修改

2.使用pthread_attr_setstacksize()函数修改线程属性


小结:

进程栈:实际上是进程可用栈空间大小,受虚拟内存大小影响,也受线程数影响,虚拟内存理论值跟系统位数有关

线程栈:程序中真正的栈分配区,受stack size影响,每个线程都有独立的栈区




不正确之处请指出。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值