Overview
In this section, you will learn the Basics about creating and handling of Threads.
With Threads, you can run multiple pieces of code in parallel.
Threads require the use of Synchronization methods to prevent race conditions.
Creating a Thread
Call fplThreadCreate() with a pointer to callback and a user pointer argument, to create and immediately run a Thread.
}
void RunMyThread() {
int myData = 42;
}
fpl_platform_api fplThreadHandle * fplThreadCreate(fpl_run_thread_callback *runFunc, void *data)
Creates and starts a thread and returns the handle to it.
fpl_platform_api bool fplThreadWaitForOne(fplThreadHandle *thread, const fplTimeoutValue timeout)
Wait until the given thread is done running or the given timeout has been reached.
#define FPL_TIMEOUT_INFINITE
Infinite timeout constant.
The thread handle structure.
- Note
- The internal Thread resources will be cleaned up automatically after your code has finished running.
- Warning
- When a Thread has finished running, you cannot use the same fplThreadHandle anymore -> It may be reassigned to another Thread in the future.
Destroying a Thread?
You don't have to manually release the Thread resources, this will be cleaned up automatically when either the Thread ends naturally or when it was terminated forcefully using fplThreadTerminate() .
- Warning
- Do not call fplThreadTerminate() to stop or release a Thread! Let the thread exit naturally.
Waiting/Joining for Threads to Exit
Wait for a single Thread to Exit
Call fplThreadWaitForOne() with a pointer to fplThreadHandle and a fplTimeoutValue argument, to wait for a single Thread to finish.
Wait for any Thread to Exit
Call fplThreadWaitForAny() to wait until at least for one Thread to finish.
Example, default thread handle array:
fpl_platform_api bool fplThreadWaitForAny(fplThreadHandle **threads, const size_t count, const size_t stride, const fplTimeoutValue timeout)
Wait until one of the given threads is done running or the given timeout has been reached.
Example, custom struct with stored thread handle:
typedef struct MyCustomStruct {
int a;
void *ptr;
short b;
} MyCustomStruct;
MyCustomStruct *customThreads;
Wait for all Threads to Exit
Call fplThreadWaitForAll() to wait for all Threads to be finished.
Example, default thread handle array:
fpl_platform_api bool fplThreadWaitForAll(fplThreadHandle **threads, const size_t count, const size_t stride, const fplTimeoutValue timeout)
Wait until all given threads are done running or the given timeout has been reached.
Example, custom struct with stored thread handle:
typedef struct MyCustomStruct {
int a;
void *ptr;
short b;
} MyCustomStruct;
MyCustomStruct *customThreads;
Terminate a thread
Call fplThreadTerminate() with a pointer to fplThreadHandle as an argument, to forcefully terminate a thread.
- Note
- Using this will almost immediately terminate the thread and releases its resources.
-
It is safe to call this when a thread is already terminated.
Query the Thread State
Call fplGetThreadState() with a pointer to fplThreadHandle as an argument, to query the current state.
If a thread is stopped or in the process of getting stopped, it will return fplThreadState_Stopped or fplThreadState_Stopping respectively.
If a thread is started or in the process of getting started, it will return fplThreadState_Running or fplThreadState_Starting respectively.
Notes
- Note
- Your code should always ensure that it will exit eventually. You can use Synchronization methods to achieve this.
-
It is bad practice to "Terminate" a thread, you should design your code to let threads end naturally.