我正在为Linux嵌入式平台开发一个多线程应用程序。
目前我正在将每个线程的堆栈大小(通过pthread_set_attr)设置为相当大的默认值。我想将每个线程的值调整为更小的值以减少应用程序的内存使用量。我可以通过试验和错误路径将每个线程的堆栈大小设置为逐渐变小的值,直到程序崩溃,但应用程序使用~15个线程,每个线程具有完全不同的功能/属性,因此这种方法非常耗时。
我更愿意直接测量每个线程的堆栈使用情况。是否有人可以推荐这样做的实用程序? (例如,我来自vxWorks背景,并使用vxWorks shell中的'ti'命令直接提供有关堆栈使用情况的统计信息以及有关任务状态的其他有用信息。)
由于
答案 0 :(得分:3)
我不知道任何好的工具,但作为最后的手段,您可以在应用程序中包含一些代码来检查它,类似于以下内容:
__thread void* stack_start;
__thread long stack_max_size = 0L;
void check_stack_size() {
// address of 'nowhere' approximates end of stack
char nowhere;
void* stack_end = (void*)&nowhere;
// may want to double check stack grows downward on your platform
long stack_size = (long)stack_start - (long)stack_end;
// update max_stack_size for this thread
if (stack_size > stack_max_size)
stack_max_size = stack_size;
}
必须在一些嵌套最深的函数中调用check_stack_size()函数。
然后作为线程中的最后一个语句,您可以将stack_max_size输出到某个地方。
必须在线程开始时初始化stack_start变量:
void thread_proc() {
char nowhere;
stack_start = (void*)&nowhere;
// do stuff including calls to check_stack_size()
// in deeply nested functions
// output stack_max_size here
}
答案 1 :(得分:3)
以下是在Linux应用程序中测量(本机pthreads)堆栈使用情况的两个工具:
<强> Valgrind的强>
用法:
valgrind --tool=drd --show-stack-usage=yes PROG
Valgrind是一款稳定而强大的工具,不仅可用于测量堆栈使用情况。但它可能不支持所有嵌入式CPU型号。
<强> Stackusage 强>
用法:
stackusage PROG
Stackusage是一款专为测量线程堆栈使用而设计的轻量级工具,对于大多数配备glibc的嵌入式Linux平台而言,它应该是可移植的。它可能不像Valgrind / drd那样经过充分测试或成熟。
完全披露:我是Stackusage的作者。
答案 2 :(得分:2)
引用Tobi的答案:如果在线程初始化时设置变量很困难,可以随时使用pthread_attr_getstackaddr
来获取堆栈的基础。然后,您可以在自己的函数中获取自动变量的地址,以确定当时堆栈的深度。