CreateThread should be replaced with _beginthreadex #17196

Closed
opened 2026-01-31 05:35:03 +00:00 by claunia · 3 comments
Owner

Originally created by @lhecker on GitHub (Apr 9, 2022).

Funny thing I just discovered:

A thread in an executable that calls the C run-time library (CRT) should use the _beginthreadex and _endthreadex functions for thread management rather than CreateThread and ExitThread; this requires the use of the multithreaded version of the CRT. If a thread created using CreateThread calls the CRT, the CRT may terminate the process in low-memory conditions.

For correctness' sake we should use std::thread (or _beginthreadex) throughout the project instead of CreateThread if possible.

Originally created by @lhecker on GitHub (Apr 9, 2022). [Funny thing I just discovered:](https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread) > A thread in an executable that calls the C run-time library (CRT) should use the `_beginthreadex` and `_endthreadex` functions for thread management rather than `CreateThread` and `ExitThread`; this requires the use of the multithreaded version of the CRT. If a thread created using `CreateThread` calls the CRT, the CRT may terminate the process in low-memory conditions. For correctness' sake we should use `std::thread` (or `_beginthreadex`) throughout the project instead of `CreateThread` if possible.
Author
Owner

@DHowett commented on GitHub (Apr 9, 2022):

Thanks for filing this! It has been kicking around in the back of my head for a while.

@DHowett commented on GitHub (Apr 9, 2022): Thanks for filing this! It has been kicking around in the back of my head for a while.
Author
Owner

@lhecker commented on GitHub (May 12, 2024):

FYI because of the PR just now I checked what the differences are:

  • It calls RoInitialize(RO_INIT_MULTITHREADED) depending on the return value of https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-apppolicygetthreadinitializationtype
    Why, Microsoft, why? What does COM got to do with C? In any case, in practice this means we get an apartment on every thread within Windows Terminal but not within conhost. I'm not sure what the cost of a RoInitialize call is.
  • Calls GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS) on start and FreeLibraryAndExitThread on exit for us to ensure DLLs remain loaded. (Neat?)
  • Wraps the call in a __try / __except. (Neat?)

It seems unlike what SO says, at some point the code was changed so that the per-thread-data was deallocated when the CRT DLL unloads (search for the __acrt_thread_detach in the CRT source folder). What I wonder now is how it does that if it's statically linked... But I guess that doesn't affect us.

@lhecker commented on GitHub (May 12, 2024): FYI because of the PR just now I checked what the differences are: * It calls `RoInitialize(RO_INIT_MULTITHREADED)` depending on the return value of https://learn.microsoft.com/en-us/windows/win32/api/appmodel/nf-appmodel-apppolicygetthreadinitializationtype Why, Microsoft, why? What does COM got to do with C? In any case, in practice this means we get an apartment on every thread within Windows Terminal but not within conhost. I'm not sure what the cost of a `RoInitialize` call is. * Calls `GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)` on start and `FreeLibraryAndExitThread` on exit for us to ensure DLLs remain loaded. (Neat?) * Wraps the call in a `__try` / `__except`. (Neat?) It seems unlike what SO says, at some point the code was changed so that the per-thread-data was deallocated when the CRT DLL unloads (search for the `__acrt_thread_detach` in the CRT source folder). What I wonder now is how it does that if it's statically linked... But I guess that doesn't affect us.
Author
Owner

@lhecker commented on GitHub (Dec 15, 2025):

I'll close this because I don't wanna do it and it's not too important.

@lhecker commented on GitHub (Dec 15, 2025): I'll close this because I don't wanna do it and it's not too important.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#17196