C++ 为什么pthread_attr_setstacksize()不适合我?

C++ 为什么pthread_attr_setstacksize()不适合我?,c++,multithreading,stack,pthreads,C++,Multithreading,Stack,Pthreads,我刚才注意到,当我使用pthread_create()生成线程时,我为线程设置自定义堆栈大小的请求似乎被忽略了。特别是,如果我从生成的线程中调用pthread_attr_getstacksize(),它总是报告默认堆栈大小,而不管我请求了什么 这种行为在Linux和MacOS/X下都可以看到,所以我怀疑我做错了什么,但我不知道是什么 要重现该问题,请编译并运行以下代码(通过“g++stack_test.cpp-lpthread;/a.out”)。它会尝试一系列不同的堆栈大小,如果请求得不到满足,

我刚才注意到,当我使用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:  %zu\n", 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:  %zu\n", 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 %i\n", 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;
}
#包括
#包括
静态void*ThreadFunc(void*pDesiredStackSize)
{
常量大小\u t desiredStackSize=*((大小*)pDesiredStackSize);
pthread_attr_t tattr;
if(pthread_attr_init(&tattr)==0)
{
大小\u t实际堆栈大小;
if(pthread_attr_getstacksize(&tattr,&actualStackSize)==0)
{
如果(实际堆栈大小==所需堆栈大小)
{
printf(“ThreadFunc:堆栈大小与预期一致:%zu\n”,实际堆栈大小);
}
其他的
{
printf(“ThreadFunc:错误,堆栈大小错误!(请求:%zu,获取:%zu)\n”,desiredStackSize,actualStackSize);
}
}
else perror(“pthread_attr_getstacksize”);
}
else perror(“pthread_attr_init(2)”;
返回NULL;
}
静态无效测试CustomStackSize(大小\u t所需的StackSizeBytes)
{
printf(“测试堆栈大小为%zu\n”的线程的创建”,desiredStackSizeBytes);
pthread_attr_t attr;
if(pthread\u attr\u init(&attr)!=0)
{
perror(“pthread_attr_init”);
返回;
}
int r=pthread_attr_setstacksize(&attr,desiredStackSizeBytes);
如果(r==0)
{
pthread\u t线程;
if(pthread_create(&thread,&attr,ThreadFunc,&desiredStackSizeBytes)==0)
{
if(pthread_join(thread,NULL)!=0)peror(“pthread_join”);
}
else perror(“pthread_create”);
}
其他的
{
perror(“pthread_attr_setstacksize”);
printf(“pthread\u attr\u setstacksize返回%i\n”,r);
}
}
int main(int argv,字符**argc)
{
const int PAGE_SIZE=8*1024;

对于(size\u t stackSizePages=1;stackSizePages,问题在于
tattr
没有引用当前线程的属性。它只是初始化为一个全新的属性,而
pthread\u attr\u getstacksize()
返回给定属性中设置的给定堆栈大小,即传递给它的属性

因此,如果将正确的属性传递给
pthread\u attr\u getstacksize()
,它应该可以工作

召唤

以前

  if (pthread_attr_getstacksize(&tattr, &actualStackSize) == 0)
而不是初始化
tattr


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

经过一些进一步的实验后,pthread_attr_setstacksize()似乎可以按预期工作,这种差异是由pthread_attr_getstacksize()引起的不返回当前线程的堆栈大小,而是返回pthread库的默认堆栈大小。如果是这样,那么问题就变成了,如何实际查询当前线程的堆栈大小?您可能在后面。虽然可能不是…这是,但没有一个答案让您感到非常满意。您可能必须找到一个plat特定于表单的解决方案,如果存在的话。
getrlimit()
Linux上有一个选项可以获取进程内的最大堆栈大小,但显然它已不再使用,所以现在可能不准确。是的,这在Linux上实现了,谢谢。在MacOS/X下,pthread_getattr_np()不可用,但是
actualStackSize=pthread\u get\u stacksize\u np(pthread\u self());
做同样的事情。我认为没有任何POSIX函数可以获得该属性。因此,如果您真的需要一个可移植的解决方案,那么您可能必须将该属性传递给线程函数。
  if (pthread_attr_getstacksize(&tattr, &actualStackSize) == 0)