1

I am working on a C++ project in which I'm trying to create hundreds of threads using the below class. If there is a few threads, everything works fine. But if I try to create 1000 threads, only around 500 (not more than 600) threads can be created. In this situation, I would like to change the default stack size of each thread.

So, how can I change the stack size?

class CThreadPool
{
    static const int MAX_THREADS = 10000;

public:

    template <typename T>
    static void QueueUserWorkItem(void (T::*function)(void),
        T *object, ULONG flags = WT_EXECUTELONGFUNCTION)
    {
        typedef std::pair<void (T::*)(), T *> CallbackType;
        std::auto_ptr<CallbackType> p(new CallbackType(function, object));
        WT_SET_MAX_THREADPOOL_THREADS(flags, MAX_THREADS);

        if (::QueueUserWorkItem(ThreadProc<T>, p.get(), flags))
        {
            // The ThreadProc now has the responsibility of deleting the pair.
            p.release();
        }
        else
        {
            throw GetLastError();
        }
    }

private:

    template <typename T>
    static DWORD WINAPI ThreadProc(PVOID context)
    {
        typedef std::pair<void (T::*)(), T *> CallbackType;

        std::auto_ptr<CallbackType> p(static_cast<CallbackType *>(context));

        (p->second->*p->first)();
        return 0;
    }
};
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
gsmaker
  • 533
  • 1
  • 4
  • 21
  • 5
    Why do you need so many threads? The point of using a thread pool is to reduce the number of threads used – Alan Birtles May 15 '20 at 06:14
  • Try BOOL SetThreadStackGuarantee( PULONG StackSizeInBytes ); – Laszlo May 15 '20 at 06:21
  • 1
    `std::auto_ptr` I thought this heresy had been purged from the standard a long time ago – Big Temp May 15 '20 at 06:24
  • 1
    @las [SetThreadStackGuarantee](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadstackguarantee) *"Sets the minimum size of the stack \[...\] that will be **available during any stack overflow exceptions**."* This is useful for handling stack overflow exceptions only. The call can only be made, once a thread has been created. At that point, there's no way to change the default stack size allotted to the thread. – IInspectable May 15 '20 at 07:36
  • 3
    I would reconsider the design of your program. It's hard to see how so many threads could be useful. – Jonathan Potter May 15 '20 at 07:38
  • You can't with standard threads. Maybe this will help. [How to set the stacksize with C++11 std::thread](https://stackoverflow.com/questions/13871763/how-to-set-the-stacksize-with-c11-stdthread) – Cosmin May 15 '20 at 14:16
  • @IInspectable Yes, correct. My bad, Well, then the only option that remains is to use the native thread API and set dwStackSize upon thread creation: [CreateThread](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread) – Laszlo May 15 '20 at 16:16

1 Answers1

2

QueueUserWorkItem() is a legacy API. It offers no way to set the stack size of the threads in its pool.

QueueUserWorkItem() was deprecated in Windows Vista, replaced by a new Thread Pool API that offers much more control. The direct replacement of QueueUserWorkItem() in this API is SubmitThreadpoolWork(). Its work items are created with CreateThreadpoolWork(), which allows an optional user-supplied TP_CALLBACK_ENVIRON struct to be passed to it to control the environment that the work item runs in.

You can create a new thread pool using CreateThreadpool(), then set the stack size for this pool's threads using SetThreadpoolStackInformation(), then create a TP_CALLBACK_ENVIRON and associate it with this pool using SetThreadpoolCallbackPool(), and then finally pass that TP_CALLBACK_ENVIRON to CreateThreadpoolWork().

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks. In current stage I am not considering to change the thread management in the project. But I will definitely consider your suggestion if so. – gsmaker May 18 '20 at 06:06