注意:
下面的测试代码在我自己的机子上(ubuntu6.06,ubuntu6.10,redhat 9, gentoo)通过了测试,但是很奇怪的是在我同事的机子上,无论是改变环境,还是想其它方法都不能正常的运行。在网上查了一下,很多人也存在同样的问题,至今不知道为何。
linux线程的实现方式决定了对进程的限制同样加在了线程身上:)所以,有问题,请参见之线程栈空间(2)(进行栈)
#include<limits.h>
#include<pthread.h>
//线程体,在栈中分配一个大小为15M的空间,并进行读写
void *thread_routine (void *arg)
{
printf ("The thread is here\n");//栈大小为16M,如果直接分配16M的栈空间,会出现段错误 ,因为栈中还有其它的
//变量要放署
char p[1024*1024*15];
int i=1024*1024*15;
//确定内存分配的确成功了
while(i--)
{
p = 3;
}
printf( "Get 15M Memory!!!\n" );
//分配更多的内存(如果分配1024*1020*512的话就会出现段错误)
char p2[ 1024 * 1020 + 256 ];
memset( p2, 0, sizeof( char ) * ( 1024 * 1020 + 256 ) );
printf( "Get More Memory!!!\n" );
return NULL;
}
int main (int argc, char *argv[])
{
pthread_t thread_id;
pthread_attr_t thread_attr;
size_t stack_size;
int status;
status = pthread_attr_init (&thread_attr);
if (status != 0)
//err_abort (status, "Create attr");
status = pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
if (status != 0)
//err_abort (status, "Set detach");
//通常出现的问题之一,下面的宏没有定义
#ifdef _POSIX_THREAD_ATTR_STACKSIZE
//得到当前的线程栈大小
status = pthread_attr_getstacksize (&thread_attr, &stack_size);
printf ("Default stack size is %u; minimum is %u\n",
stack_size, PTHREAD_STACK_MIN);
//设置当前的线程的大小
status = pthread_attr_setstacksize (&thread_attr, PTHREAD_STACK_MIN*1024);
//得到当前的线程栈的大小
status = pthread_attr_getstacksize (&thread_attr, &stack_size);
printf ("Default stack size is %u; minimum is %u\n",
stack_size, PTHREAD_STACK_MIN);
#endif
int i = 5;//分配5个具有上面的属性的线程体
while(i--)
{
status = pthread_create (&thread_id, &thread_attr, thread_routine, NULL);
//if (status != 0)
//err_abort (status, "Create thread");
}
getchar();
printf ("Main exiting\n");
pthread_exit (NULL);
return 0;
}
gcc编译
cd /root/workdir/test
gcc -pthread pthread.c -o pthread
./pthread
//注意:#ifdef _POSIX_THREAD_ATTR_STACKSIZE是否定义
看看执行过程:
dongq@DongQ_Lap ~/workspace/test/pthread_attr $ make
cc -pthread -g -DDEBUG -lrt -o thread_attr thread_attr.c
dongq@DongQ_Lap ~/workspace/test/pthread_attr $ ./thread_attr
Default stack size is 8388608; minimum is 16384 //默认的栈大小为8M
Default stack size is 16777216; minimum is 16384 //设置后的结果为16M
The thread is here
The thread is here
The thread is here
The thread is here
The thread is here
Get 15M Memory!!!
Get More Memory!!!
Get 15M Memory!!!
Get More Memory!!!
Get 15M Memory!!!
Get 15M Memory!!!
Get More Memory!!!
Get More Memory!!!
Get 15M Memory!!!
Get More Memory!!!
Main exitings 用下面的命令来看linux下面的对系统的一些限制:
dongq@DongQ_Lap ~/workspace/test/pthread_attr $ ulimit -a core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 16365
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8196
cpu time (seconds, -t) unlimited
max user processes (-u) 16365
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
通过上面的命令,我们可以清楚的看到一个进程在正常的情况下,最大的栈空间为8M。
那么8M我们够用吗?当你分配大量的static或者auto变量的时候,一般都是放在栈空间的。如果分配一个大于8M的数组,会发生什么呢?
先来看看测试代码:
int main()
{
int i = 1024 * 1024 * 8;
char p[ i ];
memset( p, 0, sizeof( char ) * i );
while( i-- )
{
p[ i ] = i;
}
return 0;
}
上面的代码直接分配一个大小为8M的数组,编译后运行,出现段错误!!
很奇怪吗?不是说可以分配8M吗?怎么不行?当然不行,因为在分配p时,栈中已经放有其它的变量,最明显的就是int i;
这样子的话,栈中就没有足够的空间给变量p分配,从而出现段错误。 |