什么是虚拟内存?
什么是进程栈?
什么是线程栈?
这几个知识点是有关联的。
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影响,每个线程都有独立的栈区
不正确之处请指出。