为什么pthread_attr_setstacksize()对我不起作用

Why is pthread_attr_setstacksize() not working for me?

本文关键字:不起作用 setstacksize pthread attr 为什么      更新时间:2023-10-16

我刚才注意到,当我使用pthread_create()生成线程时,我为该线程设置自定义堆栈大小的请求似乎被忽略了。特别是,如果我从派生的线程中调用pthread_attr_getstacksize(),它总是报告默认的堆栈大小,而不管我要求什么。

这种行为在Linux和MacOS/X下都可以看到,所以我怀疑我做错了什么,但我不知道是什么

为了重现这个问题,编译并运行下面的代码(通过"g++stack_test.cpp-lpthread;./a.out")。它尝试了一堆不同的堆栈大小,如果请求没有得到满足,就会抱怨。问题输出如下:

Jeremys-Mini:~ lcsuser1$ ./a.out 
Testing creation of a thread with stack size:  8192
ThreadFunc:  ERROR, wrong stack size!  (Requested:  8192, got: 524288)
Testing creation of a thread with stack size:  16384
ThreadFunc:  ERROR, wrong stack size!  (Requested:  16384, got: 524288)
Testing creation of a thread with stack size:  24576
ThreadFunc:  ERROR, wrong stack size!  (Requested:  24576, got: 524288)
[...]
Testing creation of a thread with stack size:  8372224
ThreadFunc:  ERROR, wrong stack size!  (Requested:  8372224, got: 524288)
Testing creation of a thread with stack size:  8380416
ThreadFunc:  ERROR, wrong stack size!  (Requested:  8380416, got: 524288)

这是代码:

#include <stdio.h>
#include <pthread.h>
static void * ThreadFunc(void * pDesiredStackSize)
{
   const size_t desiredStackSize = *((size_t *)pDesiredStackSize);
   pthread_attr_t tattr;
   if (pthread_attr_init(&tattr) == 0)
   {
      size_t actualStackSize;
      if (pthread_attr_getstacksize(&tattr, &actualStackSize) == 0)
      {
         if (actualStackSize == desiredStackSize)
         {
            printf("ThreadFunc:  Stack size is as expected:  %zun", actualStackSize);
         }
         else
         {
            printf("ThreadFunc:  ERROR, wrong stack size!  (Requested:  %zu, got: %zu)n", desiredStackSize, actualStackSize);
         }
      }
      else perror("pthread_attr_getstacksize");
   }
   else perror("pthread_attr_init(2)");
   return NULL;
}
static void TestCustomStackSize(size_t desiredStackSizeBytes)
{
   printf("Testing creation of a thread with stack size:  %zun", desiredStackSizeBytes);
   pthread_attr_t attr;
   if (pthread_attr_init(&attr) != 0)
   {
      perror("pthread_attr_init");
      return;
   }
   int r = pthread_attr_setstacksize(&attr, desiredStackSizeBytes);
   if (r == 0)
   {
      pthread_t thread;
      if (pthread_create(&thread, &attr, ThreadFunc, &desiredStackSizeBytes) == 0)
      {
         if (pthread_join(thread, NULL) != 0) perror("pthread_join");
      }
      else perror("pthread_create");
   }
   else
   {
      perror("pthread_attr_setstacksize");
      printf("pthread_attr_setstacksize returned %in", r);
   }
}
int main(int argv, char ** argc)
{
   const int PAGE_SIZE=8*1024;
   for (size_t stackSizePages=1; stackSizePages<1024; stackSizePages++) TestCustomStackSize(stackSizePages*PAGE_SIZE);
   printf("Done!n");
   return 0;
}

问题是tattr没有引用当前线程的属性。它只是被初始化为一个全新的属性,而pthread_attr_getstacksize()返回在给定属性中设置的给定堆栈大小,即传递给它的属性

因此,如果将正确的属性传递给pthread_attr_getstacksize(),它应该可以工作。

呼叫

  pthread_getattr_np(pthread_self(), &tattr);

之前

  if (pthread_attr_getstacksize(&tattr, &actualStackSize) == 0)

而不是初始化CCD_ 4。

注意pthread_getattr_np()是一个非标准函数(不在POSIX中)。