I wish to create a Thread that will always run until I force him to be close.
I programming in c language, and uses the library windows.h
adding my code of creating thread:
HANDLE thread;
DWORD threadID;
thread = CreateThread(NULL, 0, infinitePlay, (void*)*head, 0, &threadID);
if (thread)
{
// doing some work or just waiting
}
In one word (short answer), you need to call the BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode); see microsoft docs in the link term_thread function and pass to it in the hThread param the return thread from CreateThread function in your case it is thread
for long answer
consider the thread function ThreadRoutine below:
#include <windows.h>
DWORD WINAPI ThreadRoutine(void* data) {
/*Creates a thread to execute within the virtual address space of the calling process.
this function will be passed later as a functio pointer to CreateThread which will be the the application-defined function to be executed by the thread.*/
return 0;
}
Now this is the CreateThread function from microsoft_docs
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
__drv_aliasesMem LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
Function arguments
lpThreadAttributes: If lpThreadAttributes is NULL, the handle cannot be inherited by child processes.
dwStackSize: The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread uses the default size for the executable.
**lpStartAddress**:
A pointer to the application-defined function to be executed by the thread. This pointer represents the starting address of the thread. in our case its the ThreadRoutine.
lpParameter: A pointer to a variable to be passed to the thread. we can pass in void* what ever we like to pass since its a generic pointer.
dwCreationFlags: The flags that control the creation of the thread.
lpThreadId: A pointer to a variable that receives the thread identifier. If this parameter is NULL, the thread identifier is not returned.
return value
If the function succeeds, the return value is a handle to the new thread. If the function fails, the return value is NULL.
Killing the thread we have created:
BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode);
TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code. DLLs attached to the thread are not notified that the thread is terminating. The system frees the thread's initial stack.
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero.
So after reviewing all CreateThread arguments, we will use the the form below:
int main() {
HANDLE t_thread = CreateThread(NULL, 0, ThreadRoutine, NULL, 0, NULL);
if (t_thread ) {
// Optionally do stuff, such as wait on the thread or ...
/*After some time lets kill or terminate the thread we have created*/
BOOL re_term =TerminateThread(t_thread , DWORD dwExitCode);
if(re_term == 0){ //failed
/*maybe you should call GetLastError function*/
}
else{
/*killed successefully*/
}
}
return 0;
}
Related
I created a DLL that is running 3 worker threads, and the main thread is in a loop waiting for the threads to complete. The threads get created, but no execution to the threads is done.
I have tried setting MessageBox functions inside the function that gets created with CreateThread() but the box does not appear. I have also tried to debug and the return value from CreateThread() is valid so the thread gets created.
BOOL WINAPI DllMain() {
main();
return 1;
}
int main() {
HANDLE h1, h2, h3;
h1 = CreateThread(first)...
h2 = CreateThread(second)...
h3 = CreateThread(third)...
WaitForSingleObject(h3, INFINITE);
return 1;
}
first() {
MessageBoxA("print some stuff");
return;
}
I have included some pseudocode of what my layout looks like. I am unable to provide the real code due to the sensitivity of it. However this is what is happening. I use LoadLibrary in another project that loads this .DLL. The DLL gets loaded and DllMain is executed. It then calls my main function which creates 3 threads. Each thread is created. But what is inside of the thread does not execute.
EDIT:
// dllmain.cpp : Defines the entry point for the DLL application.
#include <Windows.h>
void mb() {
MessageBoxW(0, L"AAAAAAAAAAAAAAAAAAAAAAAAA", L"AAAAAAAAAAAAAAAAAAAAAAa", 1);
}
void create() {
HANDLE han;
DWORD threadId;
han = CreateThread(NULL, 0, mb, NULL, 0, &threadId);
han = CreateThread(NULL, 0, mb, NULL, 0, &threadId);
han = CreateThread(NULL, 0, mb, NULL, 0, &threadId);
}
BOOL APIENTRY DllMain() {
create();
return 1;
}
[MS.Docs]: DllMain entry point (emphasis is mine) states:
Calling functions that require DLLs other than Kernel32.dll may result in problems that are difficult to diagnose. For example, calling User, Shell, and COM functions can cause access violation errors, because some functions load other system components. Conversely, calling functions such as these during termination can cause access violation errors because the corresponding component may already have been unloaded or uninitialized.
[MS.Docs]: MessageBox function resides in User32.dll, so it's Undefined Behavior (meaning that in different scenarios, it might work, it might work faulty, or it might crash).
Also, as #RbMm noticed, WaitForSingleObject doesn't belong there. I'm not sure about CreateThread either (but I couldn't find any official doc to confirm / infirm it).
Just out of curiosity, could you add a printf("main called.\n"); in main, to see how many times it is called?
because in general case DLL can be unloaded, need add reference to DLL - for it will be not unloaded until thread, which use it code executed. this can be done by call GetModuleHandleEx - increments the module's reference count unless GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT is specified. when thread exit - we dereference DLL code by call FreeLibraryAndExitThread. wait for all threads exit in most case not need. so code, inside dll can be next
ULONG WINAPI DemoThread(void*)
{
MessageBoxW(0, L"text", L"caption", MB_OK);
// dereference dlll and exit thread
FreeLibraryAndExitThread((HMODULE)&__ImageBase, 0);
}
void someFnInDll()
{
HMODULE hmod;
// add reference to dll, because thread will be use it
if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (PCWSTR)&__ImageBase, &hmod))
{
if (HANDLE hThread = CreateThread(0, 0, DemoThread, 0, 0, 0))
{
CloseHandle(hThread);
}
else
{
// dereference dll if thread create fail
FreeLibrary(hmod);
}
}
}
wait inside dll entry point is wrong, because we hold here process wide critical section. if we wait for thread exit - this wait always deadlock - thread before exit (and start) try enter this critical section, but can not because we wait for him here. so we hold critical section and wait for thread(s), but threads(s) wait when we exit from this critical section. deadlock
I have a thread that to some operations and it needs to be alive until a flag says otherwise.
I use PsCreateSystemThread to create the thread and then use ObReferenceObjectByHandle to get ETHREAD object reference to waiting for the thread to terminate before the driver unloaded using KeWaitForSingleObject.
The function that creates the thread and retrieves a reference to it:
ntStatus = PsCreateSystemThread(
&hThread,
(ACCESS_MASK)0, NULL,
(HANDLE)0, NULL,
ThreadRoutine,
(PVOID)pThreadData
);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
ntStatus = ObReferenceObjectByHandle(
hThread,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
(PVOID*)&ptThreadObject,
NULL
);
if (!NT_SUCCESS(ntStatus))
{
bStopThread = TRUE;
ptThreadObject = NULL;
return ntStatus;
}
The thread routine:
LARGE_INTEGER liSleepTime;
while (FALSE == bThread)
{
liSleepTime.QuadPart = 1000 * RELATIVE_MILLISECOND;
KeDelayExecutionThread(KernelMode, FALSE, (&liSleepTime));
ExAcquireFastMutex(&fmMutex);
//DO SOMTHING
ExReleaseFastMutex(&fmMutex);
}
PsTerminateSystemThread(STATUS_SUCCESS);
The unload driver function:
if (NULL != ptThreadObject)
{
bStopThread = TRUE;
KeWaitForSingleObject(
(PVOID)ptThreadObject,
Executive,
KernelMode,
FALSE,
(&liTimeOut));
ObDereferenceObject((PVOID)ptThreadObject);
ptThreadObject= NULL;
}
I need this thread to run all the time.
Is there a way to check if the thread is terminated prematurely? (If it was done by PsTerminateSystemThread I can add a 'boolean' and set it before calling PsTerminateSystemThread to terminate the thread).
One more question:
I terminated the thread at the start of its routine and waited for 20 seconds before calling ObReferenceObjectByHandle and it didn't fail.
ntStatus = PsCreateSystemThread(
&hThread,
(ACCESS_MASK)0, NULL,
(HANDLE)0, NULL,
ThreadRoutine,
(PVOID)pThreadData
);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
// The ThreadRoutine calling PsTerminateSystemThread first and terminate.
liSleepTime.QuadPart = 20000 * RELATIVE_MILLISECOND;
KeDelayExecutionThread(KernelMode, FALSE, (&liSleepTime));
ntStatus = ObReferenceObjectByHandle(
hThread,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
(PVOID*)&ptThreadObject,
NULL
);
if (!NT_SUCCESS(ntStatus))
{
bStopThread = TRUE;
ptThreadObject = NULL;
return ntStatus;
}
Why does ObReferenceObjectByHandle succeed and not fail? -The thread is long gone.
Thanks.
Why does ObReferenceObjectByHandle succeed and not fail? -The thread
is long gone.
but why it must fail ?? ObReferenceObjectByHandle simply return returns the corresponding pointer to the object's body. ETHREAD in your case. the state of object - not play any role here. terminated thread or not absolute unrelated. until you have handles or referenced pointers to thread body structure (ETHREAD) - the object will be not freed. so, if hThread is valid handle - ObReferenceObjectByHandle must succeed.
How to determine if thread terminated?
very easy - simply wait on it say via KeWaitForSingleObject, which you already done. because thread objects are themselves a type of dispatcher object, when thread terminated, it set to signal state and KeWaitForSingleObject return.
if (ptThreadObject)
{
bStopThread = TRUE;
KeWaitForSingleObject(
ptThreadObject,
Executive,
KernelMode,
FALSE,
0);
ObDereferenceObject(ptThreadObject);
}
note - you must set Timeout to 0 for waits indefinitely until the thread terminated (dispatcher object is set to the signaled state). also you not need cast ptThreadObject to PVOID - it is already pointer. (PVOID)ptThreadObject is not error, but superfluous and unnecessary code.
Is there a way to check if the thread is terminated prematurely?
the operation system and i not understand what you mean under prematurely. check that thread terminated we can via wait on it. but prematurely can have sense only in context of your code. say you can set different thread exit status via PsTerminateSystemThread and than (after thread terminated) get this exist status via PsGetThreadExitStatus . if thread still running the PsGetThreadExitStatus return STATUS_PENDING. this routine can be partially used to check thread state too - if it return any status different from STATUS_PENDING - thread is terminated. but if it return STATUS_PENDING - unclear - or thread still running, or thread exist via PsTerminateSystemThread(STATUS_PENDING). of course use STATUS_PENDING as exist status is bad idea and never must be used. under this condition you can determine thread state (running/terminated) with PsGetThreadExitStatus too, but this routine not wait. but your driver logic require wait when thread terminated, and only after this we can unload driver. so only KeWaitForSingleObject (or another wait function) is correct solution here. if thread can exist in different ways - use different exit status in call PsTerminateSystemThread and get it back via PsGetThreadExitStatus after thread terminated (so after KeWaitForSingleObject)
however call to PsTerminateSystemThread is optional - you can simply return from ThreadRoutine - in this case system yourself call PsTerminateSystemThread(STATUS_SUCCESS); - so in your code call PsTerminateSystemThread(STATUS_SUCCESS); also superfluous and unnecessary code. you need call PsTerminateSystemThread only in case you want return status different from STATUS_SUCCESS and check return status after thread terminated. note that windows itself not interpret and use thread exit status. it simply store it in ETHREAD object. if you not query and use this status - does not matter what its exit status.
also liSleepTime.QuadPart = 1000 * RELATIVE_MILLISECOND; line you can out from loop - set before loop, if you use constant timeout.
also we can not wait for thread termination in driver unload at all, if use special thread entry point in asm code. obviously that driver must not be unloaded, until thread is running. for this exist 2 solution - one is wait in driver unload routine, for all drivers thread termination. but exist and another - add reference to driver object, when we create thread, and de-reference driver object, when thread exit.
so define global variable:
PDRIVER_OBJECT gDriverObject;
in DriverEntry initialize it: gDriverObject = DriverObject;
and start thread in next way:
ObfReferenceObject(gDriverObject);
NTSTATUS status = PsCreateSystemThread(
&hThread,
0, NULL,
0, NULL,
ThreadRoutine,
pThreadData
);
if (!NT_SUCCESS(status))
{
ObfDereferenceObject(gDriverObject);
}
and on thread exit need call ObfDereferenceObject(gDriverObject);. but after ObfDereferenceObject(gDriverObject); we already can not return to driver code - it can be already unloaded. so this call can not be done from c/c++ code. in user mode exist FreeLibraryAndExitThread, but in kernel mode no analog of this api. only solution - implement thread entry point in asm code - this entry call c/c++ thread routine and finally jmp (but not call) to ObfDereferenceObject.
define your c/c++ proc as
void NTAPI _ThreadRoutine(PVOID pv)
{
// not call PsTerminateSystemThread here !!
}
code for x64 and c (ml64 /c /Cp $(InputFileName) -> $(InputName).obj)
extern _ThreadRoutine : PROC
extern gDriverObject : QWORD
extern __imp_ObfDereferenceObject : QWORD
_TEXT segment 'CODE'
ThreadRoutine proc
sub rsp,28h
call _ThreadRoutine
add rsp,28h
mov rcx,gDriverObject
jmp __imp_ObfDereferenceObject
ThreadRoutine endp
_TEXT ENDS
end
code for x86 and c (ml /c /Cp $(InputFileName) -> $(InputName).obj)
.686
extern _gDriverObject:DWORD
extern __imp_#ObfDereferenceObject#4:DWORD
extern __ThreadRoutine : PROC
_TEXT SEGMENT
_ThreadRoutine proc
mov eax,[esp]
xchg eax,[esp+4]
mov [esp],eax
call __ThreadRoutine
mov ecx,_gDriverObject
jmp __imp_#ObfDereferenceObject#4
_ThreadRoutine endp
_TEXT ENDS
END
with this you can not wait fot working thread exit - simply signal to him terminate (bStopThread = TRUE;) and return from driver unload.
I have two functions:
Fl_Thread n_create_thread(Fl_Thread &t, void *(*f) (void *), void *p)
{
return t = (Fl_Thread)_beginthread((void(__cdecl *)(void *))f, 0, p);
}
void n_wait_end_thread(Fl_Thread t)
{
WaitForSingleObject((HANDLE)t, INFINITE);
}
Create thread, give pointer to thread function, but if I wait to terminate thread by WaitForSingleObject, it hangs and can't stop waiting.
Your thread handle could be invalid when you wait on it - use _beginthreadex instead - see the MSDN page:
It's safer to use _beginthreadex than _beginthread. If the thread
that's generated by _beginthread exits quickly, the handle that's
returned to the caller of _beginthread might be invalid or point to
another thread. However, the handle that's returned by _beginthreadex
has to be closed by the caller of _beginthreadex, so it is guaranteed
to be a valid handle if _beginthreadex did not return an error.
So far I've worked with processes and threads only on Linux platform.
Now I tried to move on Windows. And I got immediately stopped on very simple program.
Can you tell me why my program doesn't write anything if I remove the line with getch?
I want my thread to finish without me pressing anything.
Thank you in advance
#include <windows.h>
#include <stdio.h>
DWORD WINAPI ThreadFunc()
{
printf("lets print something");
return 0;
}
VOID main( VOID )
{
DWORD dwThreadId;
HANDLE hThread;
hThread = CreateThread(
NULL, // default security attributes
0, // use default stack size
ThreadFunc, // thread function
NULL, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
// Check the return value for success.
if (hThread == NULL)
{
printf( "CreateThread failed (%d)\n", GetLastError() );
}
else
{
_getch();
CloseHandle( hThread );
}
}
If your box is relatively idle, the OS is quilte likely to signal the thread creation request to another core, so allowing the 'main' thread, (the one created by the process loader), to run on quickly. By the time your new thread gets round to calling the OS with the printf call, the main thread has already returned, the state of all threads for that process has been set to 'never run again' and a termination request queued up for it on its inter-processor core driver. The new thread is exterminated there and then and the now-redundant termination request discarded.
My application creates a thread and that runs in the background all the time. I can only terminate the thread manually, not from within the thread callback function.
At the moment I am using TerminateThread() to kill that thread but it's causing it to hang sometimes.
I know there is a way to use events and WaitForSingleObject() to make the thread terminate gracefully but I can't find an example about that.
Please, code is needed here.
TerminateThread is a bad idea, especially if your thread uses synchronization objects such as mutexes. It can lead to unreleased memory and handles, and to deadlocks, so you're correct that you need to do something else.
Typically, the way that a thread terminates is to return from the function that defines the thread. The main thread signals the worker thread to exit using an event object or a even a simple boolean if it's checked often enough. If the worker thread waits with WaitForSingleObject, you may need to change it to a WaitForMultipleObjects, where one of the objects is an event. The main thread would call SetEvent and the worker thread would wake up and return.
We really can't provide any useful code unless you show us what you're doing. Depending on what the worker thread is doing and how your main thread is communicating information to it, it could look very different.
Also, under [now very old] MSVC, you need to use _beginthreadex instead of CreateThread in order to avoid memory leaks in the CRT. See MSKB #104641.
Update:
One use of worker thread is as a "timer", to do some operation on regular intervals. At the most trivial:
for (;;) {
switch (WaitForSingleObject(kill_event, timeout)) {
case WAIT_TIMEOUT: /*do timer action*/ break;
default: return 0; /* exit the thread */
}
}
Another use is to do something on-demand. Basically the same, but with the timeout set to INFINITE and doing some action on WAIT_OBJECT_0 instead of WAIT_TIMEOUT. In this case you would need two events, one to make the thread wake up and do some action, another to make it wake up and quit:
HANDLE handles[2] = { action_handle, quit_handle };
for (;;) {
switch (WaitForMultipleObject(handles, 2, FALSE, INFINITE)) {
case WAIT_OBJECT_0 + 0: /* do action */ break;
default:
case WAIT_OBJECT_0 + 1: /* quit */ break;
}
}
Note that it's important that the loop do something reasonable if WFSO/WFMO return an error instead of one of the expected results. In both examples above, we simply treat an error as if we had been signaled to quit.
You could achieve the same result with the first example by closing the event handle from the main thread, causing the worker thread get an error from WaitForSingleObject and quit, but I wouldn't recommend that approach.
Since you don't know what the thread is doing, there is no way to safely terminate the thread from outside.
Why do you think you cannot terminate it from within?
You can create an event prior to starting the thread and pass that event's handle to the thread. You call SetEvent() on that event from the main thread to signal the thread to stop and then WaitForSingleObject on the thread handle to wait for the thread to actually have finished. Within the threads loop, you call WaitForSingleObject() on the event, specifying a timeout of 0 (zero), so that the call returns immediately even if the event is not set. If that call returns WAIT_TIMEOUT, the event is not set, if it returns WAIT_OBJECT_0, it is set. In the latter case you return from the thread function.
I presume your thread isn't just burning CPU cycles in an endless loop, but does some waiting, maybe through calling Sleep(). If so, you can do the sleeping in WaitForSingleObject instead, by passing a timeout to it.
What are you doing in the background thread? If you're looping over something, you can end the thread within itself by having a shared public static object (like a Boolean) that you set to true from the foreground thread and that the background thread checks for and exits cleanly when set to true.
It is a code example for thread management in the fork-join manner. It use struct Thread as a thread descriptor.
Let's introduce some abstraction of the thread descriptor data structure:
#include <Windows.h>
struct Thread
{
volatile BOOL stop;
HANDLE event;
HANDLE thread;
};
typedef DWORD ( __stdcall *START_ROUTINE)(struct Thread* self, LPVOID lpThreadParameter);
struct BootstrapArg
{
LPVOID arg;
START_ROUTINE body;
struct Thread* self;
};
Functions for the thread parent use:
StartThread() initialize this structure and launches new thread.
StopThread() initiate thread termination and wait until thread will be actually terminated.
DWORD __stdcall ThreadBootstrap(LPVOID lpThreadParameter)
{
struct BootstrapArg ba = *(struct BootstrapArg*)lpThreadParameter;
free(lpThreadParameter);
return ba.body(ba.self, ba.arg);
}
VOID StartThread(struct Thread* CONST thread, START_ROUTINE body, LPVOID arg)
{
thread->event = CreateEvent(NULL, TRUE, FALSE, NULL);
thread->stop = FALSE;
thread->thread = NULL;
if ((thread->event != NULL) && (thread->event != INVALID_HANDLE_VALUE))
{
struct BootstrapArg* ba = (struct BootstrapArg*)malloc(sizeof(struct BootstrapArg));
ba->arg = arg;
ba->body = body;
ba->self = thread;
thread->thread = CreateThread(NULL, 0, ThreadBootstrap, ba, 0, NULL);
if ((thread->thread == NULL) || (thread->thread == INVALID_HANDLE_VALUE))
{
free(ba);
}
}
}
DWORD StopThread(struct Thread* CONST thread)
{
DWORD status = ERROR_INVALID_PARAMETER;
thread->stop = TRUE;
SetEvent(thread->event);
WaitForSingleObject(thread->thread, INFINITE);
GetExitCodeThread(thread->thread, &status);
CloseHandle(thread->event);
CloseHandle(thread->thread);
thread->event = NULL;
thread->thread = NULL;
return status;
}
This set of functions is expected to be used from the thread launched by StartThread():
IsThreadStopped() - Check for the termination request. Must be used after waiting on the below functions to identify the actual reason of the termination of waiting state.
ThreadSleep() - Replaces use of Sleep() for intra-thread code.
ThreadWaitForSingleObject() - Replaces use of WaitForSingleObject() for intra-thread code.
ThreadWaitForMultipleObjects() - Replaces use of WaitForMultipleObjects() for intra-thread code.
First function can be used for light-weight checks for termination request during long-running job processing. (For example big file compression).
Rest of the functions handle the case of waiting for some system resources, like events, semaphores etc. (For example worker thread waiting new request arriving from the requests queue).
BOOL IsThreadStopped(struct Thread* CONST thread)
{
return thread->stop;
}
VOID ThreadSleep(struct Thread* CONST thread, DWORD dwMilliseconds)
{
WaitForSingleObject(thread->event, dwMilliseconds);
}
DWORD ThreadWaitForSingleObject(struct Thread* CONST thread, HANDLE hHandle, DWORD dwMilliseconds)
{
HANDLE handles[2] = {hHandle, thread->event};
return WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds);
}
DWORD ThreadWaitForMultipleObjects(struct Thread* CONST thread, DWORD nCount, CONST HANDLE* lpHandles, DWORD dwMilliseconds)
{
HANDLE* handles = (HANDLE*)malloc(sizeof(HANDLE) * (nCount + 1U));
DWORD status;
memcpy(handles, lpHandles, nCount * sizeof(HANDLE));
handles[nCount] = thread->event;
status = WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds);
free(handles);
return status;
}