当前位置: 技术问答>linux和unix
unix多线程时子线程的堆和栈
来源: 互联网 发布时间:2017-01-15
本文导语: 各位好,最近刚刚接触Unix的多线程(pthread),遇到一个比较郁闷的问题,子线程有时会卡住 ,它不会往下执行,也不会core。后来查出问题,是因为有个变量new时申请空间太大了。 研究了下aix的多线程时的进程模型,...
各位好,最近刚刚接触Unix的多线程(pthread),遇到一个比较郁闷的问题,子线程有时会卡住 ,它不会往下执行,也不会core。后来查出问题,是因为有个变量new时申请空间太大了。
研究了下aix的多线程时的进程模型,如下:
它说,创建一个线程时,会在进程的堆区分配一块,作为线程栈(thread stack)使用。那线程中new出来的堆数据,是放到哪一块呢?
我写个小程序测试了下,线程主体代码如下:
创建了2个线程,结果如下:
[线程258]i_val = 0x0000000110044760
[线程258]pi = 0x0000000110047670
[线程258]pMalloc = 0x0000000110047690
[线程515]i_val = 0x000000011007b760
[线程515]pi = 0x000000011007eef0
[线程515]pMalloc = 0x000000011007ef10
照这个看来,它的堆地址和栈地址应该是在一块的,线程的堆区放在线程的栈区之后,同一个线程的栈区和堆区都放在 图中的 thread stack(96k)这个区,在Guard Page之上。
不知道我这样理解对不对?
另外,还是没办法搞清楚为什么有的程序子线程在执行的时候会卡住,而不是core掉。
请各位大侠不吝赐教!不盛感激!
研究了下aix的多线程时的进程模型,如下:
它说,创建一个线程时,会在进程的堆区分配一块,作为线程栈(thread stack)使用。那线程中new出来的堆数据,是放到哪一块呢?
我写个小程序测试了下,线程主体代码如下:
void thread_func()
{
int i_val;
printf("[线程%d]i_val = t0x%016pn",pthread_self(),&i_val);
int* pi = new int();
if(pi == NULL)
{
fprintf(stderr,"分配内存失败n");
return;
}
printf("[线程%d]pi = tt0x%016pn",pthread_self(),pi);
char* pMalloc;
if((pMalloc = (char*) malloc(10)) == NULL)
{
return;
}
printf("[线程%d]pMalloc = tt0x%016pn",pthread_self(),pMalloc);
sleep(2);
}
创建了2个线程,结果如下:
[线程258]i_val = 0x0000000110044760
[线程258]pi = 0x0000000110047670
[线程258]pMalloc = 0x0000000110047690
[线程515]i_val = 0x000000011007b760
[线程515]pi = 0x000000011007eef0
[线程515]pMalloc = 0x000000011007ef10
照这个看来,它的堆地址和栈地址应该是在一块的,线程的堆区放在线程的栈区之后,同一个线程的栈区和堆区都放在 图中的 thread stack(96k)这个区,在Guard Page之上。
不知道我这样理解对不对?
另外,还是没办法搞清楚为什么有的程序子线程在执行的时候会卡住,而不是core掉。
请各位大侠不吝赐教!不盛感激!
|
个人猜测“卡”的原因: 你new 的东西太多,超过了96K的第一个内存页,然后需要向守护页面(guard page)借一页,访问守护页面时操作系统会得到通知。系统会再commit一个页面,把下一个页面作为新的守护页面。
你把new的东西减少一下,看是不是好的?
另外附上我在linux测试的结果,线程里面的栈 和 堆 是分开的
我的代码:
在Linux下面用G++编译后结果为
[thread -1208198256]i_val= 0x0x000000b7fc53ac
[thread -1208198256] pi = 0x0x0000000804a0a0
[thread -1208198256]pmalloc = 0x0x0000000804a0b0
[thread -1216590960]i_val= 0x0x000000b77c43ac
[thread -1216590960] pi = 0x0x0000000804a158
[thread -1216590960]pmalloc = 0x0x0000000804a168
你把new的东西减少一下,看是不是好的?
另外附上我在linux测试的结果,线程里面的栈 和 堆 是分开的
我的代码:
#include
#include
#include
void* thread_func(void* arg)
{
int i_val;
printf("[thread %d]i_val= t0x%016pn",pthread_self(),&i_val);
int* pi = new int();
if(pi == NULL)
{
fprintf(stderr,"·Öä´Ã);
}
printf("[thread %d] pi = tt0x%016pn",pthread_self(),pi);
char* pMalloc;
if((pMalloc = (char*) malloc(10)) == NULL)
{
}
printf("[thread %d]pmalloc = tt0x%016pn",pthread_self(),pMalloc);
}
int main(int argc,int argv[])
{
int error;
int *temptr;
pthread_t thread_id1, thread_id2;
pthread_create(&thread_id1,NULL,thread_func,NULL);
pthread_create(&thread_id2,NULL,thread_func,NULL);
if(error=pthread_join(thread_id1,NULL))
{
perror("pthread_join");
exit(EXIT_FAILURE);
}
if(error=pthread_join(thread_id2, NULL))
{
perror("pthread_join");
exit(EXIT_FAILURE);
}
return 0;
}
在Linux下面用G++编译后结果为
[thread -1208198256]i_val= 0x0x000000b7fc53ac
[thread -1208198256] pi = 0x0x0000000804a0a0
[thread -1208198256]pmalloc = 0x0x0000000804a0b0
[thread -1216590960]i_val= 0x0x000000b77c43ac
[thread -1216590960] pi = 0x0x0000000804a158
[thread -1216590960]pmalloc = 0x0x0000000804a168