Функция CreateThread (processthreadsapi.h)
Создает поток для выполнения в виртуальном адресном пространстве вызывающего процесса.
Чтобы создать поток, который выполняется в виртуальном адресном пространстве другого процесса, используйте функцию CreateRemoteThread .
Синтаксис
HANDLE CreateThread(
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] SIZE_T dwStackSize,
[in] LPTHREAD_START_ROUTINE lpStartAddress,
[in, optional] __drv_aliasesMem LPVOID lpParameter,
[in] DWORD dwCreationFlags,
[out, optional] LPDWORD lpThreadId
);
Параметры
[in, optional] lpThreadAttributes
Указатель на структуру SECURITY_ATTRIBUTES , которая определяет, может ли возвращенный дескриптор наследоваться дочерними процессами. Если lpThreadAttributes имеет значение NULL, дескриптор не может быть унаследован.
Элемент lpSecurityDescriptor структуры указывает дескриптор безопасности для нового потока. Если lpThreadAttributes имеет значение NULL, поток получает дескриптор безопасности по умолчанию. Списки управления доступом в дескрипторе безопасности по умолчанию для потока поступают из основного токена создателя.
[in] dwStackSize
Начальный размер стека в байтах. Система округляет это значение до ближайшей страницы. Если этот параметр равен нулю, новый поток использует размер по умолчанию для исполняемого файла. Дополнительные сведения см. в разделе Размер стека потоков.
[in] lpStartAddress
Указатель на определяемую приложением функцию, выполняемую потоком. Этот указатель представляет начальный адрес потока. Дополнительные сведения о функции thread см. в разделе ThreadProc.
[in, optional] lpParameter
Указатель на переменную, передаваемую в поток.
[in] dwCreationFlags
Флаги, управляющие созданием потока.
Значение | Значение |
---|---|
|
Поток запускается сразу после создания. |
|
Поток создается в приостановленном состоянии и не выполняется до вызова функции ResumeThread . |
|
Параметр dwStackSize указывает начальный размер резерва стека. Если этот флаг не указан, dwStackSize указывает размер фиксации. |
[out, optional] lpThreadId
Указатель на переменную, которая получает идентификатор потока. Если этот параметр имеет значение NULL, идентификатор потока не возвращается.
Возвращаемое значение
Если функция выполняется успешно, возвращаемое значение является дескриптором для нового потока.
Если функция завершается сбоем, возвращается значение NULL. Дополнительные сведения об ошибке можно получить, вызвав GetLastError.
Обратите внимание, что CreateThread может завершиться успешно, даже если lpStartAddress указывает на данные, код или недоступен. Если начальный адрес недействителен при выполнении потока, возникает исключение и поток завершается. Завершение потока из-за недопустимого начального адреса обрабатывается как выход из процесса потока. Это поведение аналогично асинхронной природе CreateProcess, где процесс создается, даже если он ссылается на недопустимые или отсутствующие библиотеки динамической компоновки (DLL).
Комментарии
Количество потоков, которые может создать процесс, ограничено доступной виртуальной памятью. По умолчанию каждый поток имеет один мегабайт пространства стека. Таким образом, невозможно создать 2048 или более потоков в 32-разрядной системе без /3GB
boot.ini параметра. Если уменьшить размер стека по умолчанию, можно создать дополнительные потоки. Однако производительность приложения будет выше, если вы создадите один поток для каждого процессора и создадите очереди запросов, для которых приложение хранит сведения о контексте. Поток будет обрабатывать все запросы в очереди перед обработкой запросов в следующей очереди.
Новый дескриптор потока создается с правом доступа THREAD_ALL_ACCESS . Если дескриптор безопасности не предоставляется при создании потока, для нового потока создается дескриптор безопасности по умолчанию с использованием основного маркера процесса, создающего поток. Когда вызывающий объект пытается получить доступ к потоку с помощью функции OpenThread , фактический токен вызывающего объекта оценивается по этому дескрипторову безопасности, чтобы предоставить или запретить доступ.
Созданный поток имеет права полного доступа к себе при вызове функции GetCurrentThread .
Windows Server 2003: Права доступа потока к самому себе вычисляются путем вычисления основного маркера процесса, в котором был создан поток, с помощью дескриптора безопасности по умолчанию, созданного для потока. Если поток создается в удаленном процессе, используется основной маркер удаленного процесса. В результате вновь созданный поток может иметь ограниченные права доступа к себе при вызове GetCurrentThread. Некоторые права доступа , включая THREAD_SET_THREAD_TOKEN и THREAD_GET_CONTEXT , могут отсутствовать, что приведет к непредвиденным сбоям. По этой причине создавать поток при олицетворении другого пользователя не рекомендуется.
Если поток создается в состоянии запуска (то есть, если флаг CREATE_SUSPENDED не используется), поток может начать выполнение до возврата CreateThread и, в частности, до того, как вызывающий объект получит дескриптор и идентификатор созданного потока.
Выполнение потока начинается с функции, указанной параметром lpStartAddress . Если эта функция возвращает значение, возвращаемое значение DWORD используется для завершения потока в неявном вызове функции ExitThread . Используйте функцию GetExitCodeThread , чтобы получить возвращаемое значение потока.
Поток создается с приоритетом потока THREAD_PRIORITY_NORMAL. Используйте функции GetThreadPriority и SetThreadPriority , чтобы получить и задать значение приоритета потока.
Когда поток завершается, объект потока достигает сигнального состояния, удовлетворяющего всем потокам, ожидающим объекта.
Объект потока остается в системе до тех пор, пока поток не завершит работу и все его дескрипторы не будут закрыты посредством вызова CloseHandle.
Функции ExitProcess, ExitThread, CreateThread, CreateRemoteThread и процесс, который запускается (в результате вызова Метода CreateProcess), сериализуются друг между другом в рамках процесса. Только одно из этих событий может происходить в адресном пространстве одновременно. Это означает, что следующие ограничения удерживают:
- Во время запуска процесса и процедур инициализации DLL можно создавать новые потоки, но они не начинают выполнение, пока не будет выполнена инициализация DLL для процесса.
- В процедуре инициализации или отсоединения DLL одновременно может находиться только один поток в процессе.
- ExitProcess не завершается до тех пор, пока в подпрограммах инициализации или отсоединения БИБЛИОТЕК DLL отсутствуют потоки.
Windows Phone 8.1. Эта функция поддерживается для приложений магазина Windows Phone в Windows Phone 8.1 и более поздних версиях.
Windows 8.1 и Windows Server 2012 R2. Эта функция поддерживается для приложений Магазина Windows на Windows 8.1, Windows Server 2012 R2 и более поздних версиях.
Примеры
Пример см. в разделе Создание потоков.
Требования
Требование | Значение |
---|---|
Минимальная версия клиента | Windows XP [классические приложения | Приложения UWP] |
Минимальная версия сервера | Windows Server 2003 [классические приложения | Приложения UWP] |
Целевая платформа | Windows |
Header | processthreadsapi.h (включая Windows.h в Windows Server 2003, Windows Vista, Windows 7, Windows Server 2008 Windows Server 2008 R2) |
Библиотека | Kernel32.lib; WindowsPhoneCore.lib в Windows Phone 8.1 |
DLL | Kernel32.dll; KernelBase.dll Windows Phone 8.1 |