我在ubuntu 9.04,gcc4.4.1环境下进行该实验,证明线程的栈确实有固定大小,也就是ulimit   -a显示的那个值,在我的实验室环境下为8M字节 
  实验1: 
  #include   <stdio.h> 
  #include   <pthread.h> 
  
  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   <stdio.h> 
  #include   <pthread.h> 
  
  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   <stdio.h> 
  #include   <pthread.h> 
  
  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   <stdio.h> 
  
  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   <stdio.h> 
  #include   <pthread.h> 
  
  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显示的值
 
 
 

Logo

更多推荐