Chinaunix首页 | 论坛 | 博客
  • 博客访问: 121757
  • 博文数量: 54
  • 博客积分: 2986
  • 博客等级: 少校
  • 技术积分: 600
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-18 10:26
文章分类

全部博文(54)

文章存档

2012年(2)

2011年(16)

2010年(36)

我的朋友

分类: C/C++

2010-04-26 15:09:13

我在ubuntu 9.04,gcc4.4.1环境下进行该实验,证明线程的栈确实有固定大小,也就是ulimit   -a显示的那个值,在我的实验室环境下为8M字节  
  实验1:  
  #include    
  #include    
   
  int   i   =   0;  
   
  void   *test(void   *   s)   {  
      int   buffer[1024];  
      printf("i=%d\n",   i);  
      i++;  
      test(s);  
  }  
   
  int   main()   {  
      pthread_t   p;  
   
      pthread_create(&p,   NULL,   &test,   NULL);  
      sleep(100);  
  }  
   
   结果在i=2029之后出现断错误

  并且可以使用如下代码修改这个线程栈的大小为16M:  
  实验2:  
  #include    
  #include    
   
  int   i   =   0;  
   
  void   *test(void   *   s)   {  
      int   buffer[1024];  
      printf("i=%d\n",   i);  
      i++;  
      test(s);  
  }  
   
  int   main()   {  
      pthread_t   p;  
      pthread_attr_t   tattr;  
      void   *stack;  
   
      pthread_attr_init(&tattr);  
   
      stack=malloc(16*1024*1024);  
      pthread_attr_setstack(&tattr,stack,16*1024*1024);   //注意这个空间应该从堆中分配,如果从栈中分配,就会出现另一个问题,我们后面会提到  
      pthread_create(&p,   &tattr,   &test,   NULL);  
      sleep(100);  
  }  
  结果在4062时出现断错误

  但是如果用两个线程使用默认大小,来进行上面的实验,两个栈的总和并不是一个线程的二倍,并且这个总和也不是固定值  
  实验3:  
  #include    
  #include    
   
  int   i   =   0;  
  pthread_mutex_t   mutex=PTHREAD_MUTEX_INITIALIZER;  
   
  void   *test(void   *   s)   {  
      int   buffer[1024];  
      pthread_mutex_lock(&mutex);  
      printf("i=%d\n",   i);  
      i++;  
      pthread_mutex_unlock(&mutex);  
      test(s);  
  }  
   
  int   main()   {  
      pthread_t   p1,p2;  
      pthread_create(&p1,   NULL,   &test,   NULL);  
      pthread_create(&p2,   NULL,   test,   NULL);  
      sleep(100);  
  }  
  结果为3740

  如果不使用任何线程的话,那么一个进程的栈也不是理论上的2G,而是比一个线程的栈稍(ulimit   -a   的值8M)大一些,并且这个栈的大小也不总是固定的  
  实验4:  
  #include    
   
  int   i=0;  
   
  void   fun()  
  {  
                  int   buffer[1024];  
                  printf("i=%d\n",i);  
                  i++;  
                  fun();  
  }  
   
  int   main()  
  {  
                  fun();  
                  sleep(100);  
  }  
   
  如果pthread_attr_setstack设置的线程栈是从栈空间分配的话,如果线程栈的大小为8M的话,那么线程栈的大小也不是固定不变了而是和实验4的结果相同(类似?)  
  如果线程栈大小为9M的话,那么线程栈的大小也不是固定不变,但这个时候有可能在进程一开始的时候就发生段错误,即使是同一个可执行文件多次不同执行也会出现这种现象,说明这个栈的大小是和gcc的编译与链接无关的  
   
  实验5:  
  #include    
  #include    
   
  int   i   =   0;  
   
  void   *test(void   *   s)   {  
      int   buffer[1024];  
      printf("i=%d\n",   i);  
      i++;  
      test(s);  
  }  
   
  int   main()   {  
      pthread_t   p;  
      pthread_attr_t   tattr;  
      char   stack[9*1024*1024];  
   
      pthread_attr_init(&tattr);  
   
      pthread_attr_setstack(&tattr,&stack[0],9*1024*1024);  
      pthread_create(&p,   &tattr,   &test,   NULL);  
      sleep(100);  
  }  
   
  结论:  
  1.   进程的栈大小是在进程执行的时刻才能指定的,即不是在编译的时刻决定,也不是链接的时刻决定,否则就不会有实验5的结果  
  2.   进程的栈大小是随机确定的至少比线程的栈要大,但是不到线程栈大小的2倍  
  3.   线程栈的大小是固定的,也就是ulimit   -a显示的值
阅读(805) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~