DWORD WINAPI BackgroundThread_Loop( LPVOID lpParam )
{
bool quit = false;
while(!quit)
{
//Read messages from main thread
//Do stuff
//Send messages to Main thread
}
}
how do you alter the local bool quit variable so that thread returns?
As rip-off showed, lpParam is a pointer to the LOADER object, provided you passed 'this' as the corresponding argument of CreateThread. Since the function is class-static, it has access to private members, including (for example) any boolean flags you put in the object pointed to by lpParam.
However, beware that simply accessing a bool in a loop without proper synchronization may or may not work, depending on the compiler you're using, the optimizations enabled in your build, the architecture of the target machine, and many other subtleties.
In many situations, a compiler is allowed to keep a cached copy of a boolean flag if it can deduce that no changes are made to it. Really, you should do one of the following:
- use an std::atomic<bool>, added in C++11 (or similar)
- or the bool should be accessed under the protection of a mutex
- or you should wait using a synchronization primtive such as a condition variable, Windows Event or a Semaphore.
On Visual C++, it is tempting to declare flags as volatile as Microsoft's compiler embues small-enough volatiles with load-acquire/store-release semantics and implicit compiler reordering barriers. But take care there, because that isn't sufficient for every possible use of 'atomic bools'. Other compilers also do no such thing for volatile variables (as they aren't required to do so). A proper threading primitive should be preferred.
Also general advice to threading would be:
-1 threads run or return and share memory between other threads of the process (Process is an OS object it does not run)
-2 threads run paralell (even on 1 core-taskmgr.exe), if they write or read shared data you may need to synchronize them.
-3 messaging should be applied in the scope of shared memory and have threads check them recently
[/quote]
I don't understand these options. Avoiding mutable shared state where possible is definitely a good thing. Polling (is that what you're saying in '-3'?) is often bad, especially on devices running off batteries.
for example, but this type of messaging cannot be applyied if you wish threads to rest adn not use CPU.
[/quote]
Indeed, using semaphores/condition variables/events, you can have threads wait for things to happen without wasting cycles. I tend to prefer condition variables for most things, but each has its place.
If you wish threads not use CPU and have ability to invoke them with data, I would not advice to use Thread::Sleep(), for you rely on taskmgr.exe , but use a trick of synchronous Socket::Listen() function on a local socket
[/quote]
That would probably be considered an abuse of sockets unless you have threads waiting on I/O exclusively. Again, semaphores, condition variables, events.
However, if your application is spread across multiple OS processes, then that will help to minimize shared state and using sockets may well be an appropriate communication mechanism.
following thread function will use 1 core fully loaded to 100% on Windows, thats why I like windows, it is such a naive lover of aplications:)
void ThreadFunc(void* sharedanchor)
{
CClient* client=(CClient*)sharedanchor;
while (client.m_bRun)
{
}
}
[/quote]
Where has this come from? The first question you asked seemed to imply that you did not understand this mechanism, and yet here you've just answered your own question (?!)
But again, you need to make sure client.m_bRun is accessed in an appropriately thread-safe manner.
So this is following abstraction I would use for Threads on c++;
#include <windows.h>
public statis class CThreadExecutor
[/quote]
Is this managed C++? static classes aren't in regular C++.
{
public static bool RunThread(void* anchordata,DWORD WINAPI(*fncMethodPointer)(LPVOID) )// I will define this function inline
{
HANDLE id= CreateThread(
NULL, // default security attributes
0, // use default stack size
fncIdleMethod, // thread function name
(LPVOID)anchordata, // argument to thread function
0, // use default creation flags
NULL); //
if (!id)
return false;
else
return true;
};
}
[/quote]
Such a function would cause a resource leak should you ever need to wait for the thread to finish (in which case, the handle should be closed). Take a look at the thread classes in boost, poco, the C++ standard, C#, Java, etc and see how they've been done (and their respective tradeoffs).