发现用 ACE 写的多线程程序随便就占用了上百兆内存,查看 /proc//maps 发现有很多 10M 大的内存段,用 gdb attach 上去,p 一下 $esp 可以确定那些 10M 的内存段就是线程栈。这怎么可以,我用不到这多堆栈的。于是按照 ACE 的文档设定了线程栈大小,结果发现还是没有效果 @_@

  读了一下 ACE 的代码,发现原来是 ACE 的一个 bug, ACE 里面创建线程最后是通过 ACE_OS::thr_create 函数来创建的,该函数里面关于 stack size 的处理代码如下:
OS_NS_Thread.cpp:2288

# if defined (ACE_HAS_PTHREAD_SETSTACK)
if ((stacksize != 0) && (stack != 0))
# else
if (stacksize != 0)
# endif /* ACE_HAS_PTHREAD_SETSTACK */
{
size_t size = stacksize;

# if defined (PTHREAD_STACK_MIN)
if (size < ACE_static_cast (size_t, PTHREAD_STACK_MIN)) size = PTHREAD_STACK_MIN; # endif /* PTHREAD_STACK_MIN */ # if !defined (ACE_LACKS_THREAD_STACK_SIZE) // JCEJ 12/17/96 # if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6) if (::pthread_attr_setstacksize (&attr, size) != 0) # else # if defined (ACE_HAS_PTHREAD_SETSTACK) if (ACE_ADAPT_RETVAL(pthread_attr_setstack (&attr, stack, size), result) == -1) # else if (ACE_ADAPT_RETVAL(pthread_attr_setstacksize (&attr, size), result) == -1) # endif /* ACE_HAS_PTHREAD_SETSTACK */ # endif /* ACE_HAS_PTHREADS_DRAFT4, 6 */ { # if defined (ACE_HAS_PTHREADS_DRAFT4) ::pthread_attr_delete (&attr); # else /* ACE_HAS_PTHREADS_DRAFT4 */ ::pthread_attr_destroy (&attr); # endif /* ACE_HAS_PTHREADS_DRAFT4 */ return -1; } # else ACE_UNUSED_ARG (size); # endif /* !ACE_LACKS_THREAD_STACK_SIZE */ }

在 linux 下面编译时候,ACE_HAS_PTHREAD_SETSTACK 会被定义,于是设置线程栈参数会通过 ::pthread_attr_setstack 来设置,如果我并不想指定 stack 的地址,只设置默认 stack 的大小,ACE 代码也会通过 ::pthread_attr_setstack , 但是这个函数如果不指定 stack 地址的话,就忽略了 stacksize 。

最后用了比较垃圾的解决方案,在这段代码前面 #undef 掉 ACE_HAS_PTHREAD_SETSTACK ,这样设置就会通过 ::pthread_attr_setstacksize 来作,于是就有效了。。