Creating threads in windows

How to create threads in dlls (c++)?

I know I cannot create threads from DllMain, but what is the correct approach for creating threads in a DLL?

I tried to create a class that wraps around it and declare a global instance of that class, but then WaitForSingleObject hangs in the destructor of the class, even though I’m certain that the thread has exited.

Here is my sample program to load the dll from an exe:

And here is the dll code:

This is the program output:

What is wrong with this approach?

If I happen to remove the Sleep(1000) from run_thread, so that the thread finishes before WaitForSingleObject is called, then it does not hang:

I don’t understand the difference, and that is also not an option, since the purpose of the thread is to loop constantly while DLL_PROCESS_DETACH is not signaled.

1 Answer 1

I know I cannot create threads from DllMain, but what is the correct approach for creating threads in a DLL?

After the main application loaded the dll (either implicitly or explicitly through LoadLibrary ), it calls some function exported by your dll, which can do whatever it likes, including launching threads.

I tried to create a class that wraps around it and declare a global instance of that class

Initialization (destruction) of global objects happens inside DllMain as well; the «real» DllMain entrypoint (which is the one MSDN talks about) is taken by the CRT which uses it to initialize (destroy) globals & co. and then invoke your DllMain .

In this answer to a similar question (it’s about LoadLibrary instead of CreateThread , but much of it apply to this case as well) you can find some more details.

What is wrong with this approach?

It’s wrong that you are trying to do complex stuff inside DllMain , in particular stuff that is explicitly discouraged; ideally DllMain should just be empty or do extremely trivial work.

Most probably, in this specific case the thread being terminated is trying to call again DllMain for a DLL_THREAD_DETACH notification, but is being locked out either because there’s an implicit mutex that prevents concurrent access to DllMain , or because Windows is explicitly forbidding a DLL_THREAD_DETACH notification from arriving after a DLL_PROCESS_DETACH .

This wouldn’t surprise me — after all, as Hans Passant notes, calling FreeLibrary with code still running is obviously undefined behavior. It’s not a chance that there’s a specific function ( FreeLibraryAndExitThread ) to let a thread holding a reference to the library atomically free the library and kill itself.

Multithreading: Creating Worker Threads in MFC

A worker thread is commonly used to handle background tasks that the user should not have to wait for to continue using your application. Tasks such as recalculation and background printing are good examples of worker threads. This topic details the steps necessary to create a worker thread. Topics include:

Creating a worker thread is a relatively simple task. Only two steps are required to get your thread running: implementing the controlling function and starting the thread. It is not necessary to derive a class from CWinThread. You can derive a class if you need a special version of CWinThread , but it is not required for most simple worker threads. You can use CWinThread without modification.

Читайте также:  Grub windows с другого диска

Starting the Thread

There are two overloaded versions of AfxBeginThread : one that can only create worker threads, and one that can create both user-interface threads and worker threads. To begin execution of your worker thread using the first overload, call AfxBeginThread, providing the following information:

The address of the controlling function.

The parameter to be passed to the controlling function.

(Optional) The desired priority of the thread. The default is normal priority. For more information about the available priority levels, see SetThreadPriority in the Windows SDK.

(Optional) The desired stack size for the thread. The default is the same size stack as the creating thread.

(Optional) CREATE_SUSPENDED if you want the thread to be created in a suspended state. The default is 0, or start the thread normally.

(Optional) The desired security attributes. The default is the same access as the parent thread. For more information about the format of this security information, see SECURITY_ATTRIBUTES in the Windows SDK.

AfxBeginThread creates and initializes a CWinThread object for you, starts it, and returns its address so you can refer to it later. Checks are made throughout the procedure to make sure all objects are deallocated properly should any part of the creation fail.

Implementing the Controlling Function

The controlling function defines the thread. When this function is entered, the thread starts, and when it exits, the thread terminates. This function should have the following prototype:

The parameter is a single value. The value the function receives in this parameter is the value that was passed to the constructor when the thread object was created. The controlling function can interpret this value in any manner it chooses. It can be treated as a scalar value or a pointer to a structure containing multiple parameters, or it can be ignored. If the parameter refers to a structure, the structure can be used not only to pass data from the caller to the thread, but also to pass data back from the thread to the caller. If you use such a structure to pass data back to the caller, the thread needs to notify the caller when the results are ready. For information about communicating from the worker thread to the caller, see Multithreading: Programming Tips.

When the function terminates, it should return a UINT value indicating the reason for termination. Typically, this exit code is 0 to indicate success with other values indicating different types of errors. This is purely implementation dependent. Some threads might maintain usage counts of objects and return the current number of uses of that object. To see how applications can retrieve this value, see Multithreading: Terminating Threads.

There are some restrictions on what you can do in a multithreaded program written with the MFC library. For descriptions of these restrictions and other tips about using threads, see Multithreading: Programming Tips.

Controlling Function Example

The following example shows how to define a controlling function and use it from another portion of the program.

Читайте также:  Windows system character encoding

Creating Threads

The CreateThread function creates a new thread for a process. The creating thread must specify the starting address of the code that the new thread is to execute. Typically, the starting address is the name of a function defined in the program code (for more information, see ThreadProc). This function takes a single parameter and returns a DWORD value. A process can have multiple threads simultaneously executing the same function.

The following is a simple example that demonstrates how to create a new thread that executes the locally defined function, MyThreadFunction .

The calling thread uses the WaitForMultipleObjects function to persist until all worker threads have terminated. The calling thread blocks while it is waiting; to continue processing, a calling thread would use WaitForSingleObject and wait for each worker thread to signal its wait object. Note that if you were to close the handle to a worker thread before it terminated, this does not terminate the worker thread. However, the handle will be unavailable for use in subsequent function calls.

The MyThreadFunction function avoids the use of the C run-time library (CRT), as many of its functions are not thread-safe, particularly if you are not using the multithreaded CRT. If you would like to use the CRT in a ThreadProc function, use the _beginthreadex function instead.

It is risky to pass the address of a local variable if the creating thread exits before the new thread, because the pointer becomes invalid. Instead, either pass a pointer to dynamically allocated memory or make the creating thread wait for the new thread to terminate. Data can also be passed from the creating thread to the new thread using global variables. With global variables, it is usually necessary to synchronize access by multiple threads. For more information about synchronization, see Synchronizing Execution of Multiple Threads.

The creating thread can use the arguments to CreateThread to specify the following:

  • The security attributes for the handle to the new thread. These security attributes include an inheritance flag that determines whether the handle can be inherited by child processes. The security attributes also include a security descriptor, which the system uses to perform access checks on all subsequent uses of the thread’s handle before access is granted.
  • The initial stack size of the new thread. The thread’s stack is allocated automatically in the memory space of the process; the system increases the stack as needed and frees it when the thread terminates. For more information, see Thread Stack Size.
  • A creation flag that enables you to create the thread in a suspended state. When suspended, the thread does not run until the ResumeThread function is called.

You can also create a thread by calling the CreateRemoteThread function. This function is used by debugger processes to create a thread that runs in the address space of the process being debugged.

What is thread?How to create thread in win32 application?

What is thread? How to create thread in win32 application?

5 Answers 5

Thread is a light weight process. A thread can be loosely defined as a separate stream of execution that takes place simultaneously with and independently of everything else that might be happening. A thread is like a classic program that starts at point A and executes until it reaches point B. It does not have an event loop. A thread runs independently of anything else happening in the computer. Without threads an entire program can be held up by one CPU intensive task or one infinite loop, intentional or otherwise. With threads the other tasks that don’t get stuck in the loop can continue processing without waiting for the stuck task to finish. Please go through this link for more detail and its comparision with process.

Читайте также:  Linux для ноутбука 2021 года

Creating thread is very easy for an example go through this.

This is a very example which creates thread i.e ThreadFun1

Don’t use CreateThread(), use _beginthreadex() instead if you are writing C/C++ programs.

_beginthreadex() will initialize the C/C++ runtime, but CreateThread() won’t.

A thread is the context that currently occupies the CPU and is the part that is scheduled by Windows CE.

To create a thread use CreateThread . You can read about more threading and process functions here.

This information is correct for Windows CE 6 as well.

Very popular is explained in Wikipedia 🙂

What about how to handle it, you can read by ex the

All these answers suggest to use CreateThread()

That is simply poor advice.

Threads should generally be created with _beginthread() or _beginthreadex() to ensure the C/C++ runtime thread-local structures are appropriately initialised.

How do I create and show WPF windows on separate threads?

I need to create two (or more) WPF windows from the same process. But the windows must be handled by separate threads because they should not be able to block each other. How do I do this?

In WinForms this is achieved by:

  • Start a new thread
  • Create a form from the new thread
  • Call Application.Run with the form as parameter

But how do I do the same in WPF?

4 Answers 4

EDIT: this IS an old answer, but since it seems to be visited often, I could also think of the following modifications/improvements (not tested).

If you would like to close such a window, simply keep a reference to the Window object from outside of the thread (delegate), and then invoke close on it, something like this:

If the new thread could become terminated (aborted forcibly), in line with question in comments:

DISCLAIMER: don’t do this at home, aborting threads is (almost always) against best practices. Threads should be gracefully handled via any of the various synchronization techniques, or in this case, simply via an invoked window.Close()

For whatever it is worth, since this answer is the first result provided by Google. I would also like to add the following taken from Eugene Prystupa’s Weblog:

«There is one catch to our simplified solution. Closing a particular window does NOT terminate this window’s thread dispatcher, so the thread keeps running and, after closing all windows, the process will not terminate and will become a ghost process. [The] Simple (and not correct) solution to this is to mark our threads as background (using thread.IsBackground = true;). This will force them to terminate when main UI thread terminates.

The proper implementation will gracefully shut down the dispatcher when it is no longer needed. The code below is an example of a strategy to terminate the dispatcher when window closes

Оцените статью