线程有自己的堆栈,但共享相同的堆[请参阅:Do threads have a distinct heap?]。
但是,有人可以解释以下程序的输出吗?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void f(void)
{
char *pt = malloc(1024);
printf(" f(). stack: %p, malloc: %p\n", &pt, pt);
}
void *thread_func(void *i)
{
char *pt = malloc(1024);
printf("thread(). stack: %p, malloc: %p\n", &pt, pt);
return NULL;
}
int main(void)
{
char *pt = malloc(1024);
printf(" main(). stack: %p, malloc: %p\n", &pt, pt);
f();
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, thread_func, NULL);
pthread_create(&thread2, NULL, thread_func, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
while(1);
return 0;
}
[/tmp/t1]$ a.out
main(). stack: 0x7fff9bedff88, malloc: 0x1527010 -> using same stack and heap with f()
f(). stack: 0x7fff9bedff48, malloc: 0x1527420 -> using same stack and heap with main()
thread(). stack: 0x7f3c67378ea8, malloc: 0x7f3c580008c0 -> own stack and heap? (first thread)
thread(). stack: 0x7f3c67d79ea8, malloc: 0x7f3c600008c0 -> own stack and heap? (second thread)
$ pmap 106202
106202: a.out
0000000000400000 4K r-x-- /tmp/t1/a.out
0000000000600000 4K rw--- /tmp/t1/a.out
0000000001527000 132K rw--- [ anon ] -> heap for main() and f()
0000003c57200000 128K r-x-- /lib64/ld-2.12.so
0000003c5741f000 4K r---- /lib64/ld-2.12.so
0000003c57420000 4K rw--- /lib64/ld-2.12.so
0000003c57421000 4K rw--- [ anon ]
0000003c57600000 1576K r-x-- /lib64/libc-2.12.so
0000003c5778a000 2044K ----- /lib64/libc-2.12.so
0000003c57989000 16K r---- /lib64/libc-2.12.so
0000003c5798d000 4K rw--- /lib64/libc-2.12.so
0000003c5798e000 20K rw--- [ anon ]
0000003c57e00000 92K r-x-- /lib64/libpthread-2.12.so
0000003c57e17000 2048K ----- /lib64/libpthread-2.12.so
0000003c58017000 4K r---- /lib64/libpthread-2.12.so
0000003c58018000 4K rw--- /lib64/libpthread-2.12.so
0000003c58019000 16K rw--- [ anon ]
00007f3c58000000 132K rw--- [ anon ] -> malloc (first thread)
00007f3c58021000 65404K ----- [ anon ]
00007f3c60000000 132K rw--- [ anon ] -> malloc (second thread)
00007f3c60021000 65404K ----- [ anon ]
00007f3c66979000 4K ----- [ anon ]
00007f3c6697a000 10240K rw--- [ anon ] -> stack (10240K) (first thread)
00007f3c6737a000 4K ----- [ anon ]
00007f3c6737b000 10252K rw--- [ anon ] -> stack (10252K?) (second thread)
00007f3c67d88000 8K rw--- [ anon ]
00007fff9becc000 84K rw--- [ stack ] -> stack for main() and f()
00007fff9bf42000 4K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
total 157776K
似乎两个线程有不同的堆栈和堆。
另一个问题是ulimit -s
显示10240,但是一个线程的堆栈是10240K,另一个是10252K。
该程序在64位计算机上运行。操作系统:红帽企业Linux服务器版本6.4(圣地亚哥),内核:2.6.32,以及gcc:4.4.7。
感谢。
----更新:
使用32位操作系统(Ubuntu 12.04),发现两个线程只有一个堆区域。但它仍然是一个与main()和f()堆不同的区域。
任何人都可以尝试使用自己的机器进行验证吗?
在上面的链接和其他资源中,人们说所有线程都有一个堆,因为线程必须共享数据。任何人都可以举例说明两个线程如何通过堆共享数据?如果32位操作系统有一个堆并且线程可以用来共享,那么原始64位操作系统示例中的不同堆如何呢?
感谢。
答案 0 :(得分:2)
最重要的部分:堆是一个实现细节,就像堆栈一样,并且有许多不同的方法来实现它。
实际上,桌面或服务器环境的每个严肃实现都将使用某种线程本地存储,因为您希望最小化同步开销。对于一个众所周知的示例,请参阅tcmalloc。因此,分配最终将在地址空间的不同部分结束并不特别令人惊讶(尽管即使使用简单的malloc也可以相对容易地进行分配 - 例如,首先适用于免费列表)