I rewriting some code that i written a long time ago.
The code is a class that start another worker thread with AfxBeginThread. When the thread ends, it needs to return it work to the calling class.
Actually when the thread ends it send a message by PostMessage with its results to the called class.
But this way is really dependent of MFC, and to do this my class have to implement all the MFC stuffs.
May be correct if instead of send a message it directly call a non-static method of this class ?
Rather than trying to call a method directly (which will introduce a whole new set of threading problems of its own), try using the native Win32 ::PostMessage() instead of the MFC implementation of the same function. Any thread can call ::PostMessage() to deliver a message to another thread safely.
It sounds as though you want to use regular threading primitives, not window messaging primitives.
Which version of AfxBeginThread are you using? If you pass it a class instance, you should be able to access the members of that class directly once you know its finished running. If you passed it a function pointer, you can pass any class pointer in with the lParam parameter, then use that as a communication context.
You just want to make sure that when you access the class you do it in a thread safe manner. If you wait till the thread has ended you should be fine. Otherwise you could use Critical Sections or Mutexes. See the MSDN article on thread synchronization primitives for more info.
Related
I have a shared C library, that read data from COM port in a separate thread.
And a C++ wxWidget application, that wait a data from lib and render it in UI.
I need to make a callback function, that lib will call, when collect a correct packet of data.
I've made a static var in wxWidget frame class, which contain a pointer to the object of this class and a static method, pointer to which I give to a library as a callback. Thats callback work, but in this cause I can't modify the UI. The program crashed with SIGABRT signal. As I see, it's a bad way to modify an wxWidgets UI from a non-main thread. But I dont know how to do it another. Can you help me? Thank you.
Yes, you can only use wxWidgets GUI functions from a single (commonly called "main", but it doesn't have to be the actual main thread of the application, just the one from which wxWidgets was initialized) thread. The only thing you can do from another thread safely is to post an event to the GUI thread asking it to perform something on this thread behalf, see wxQueueEvent().
Since wxWidgets 3.0 there is a convenient wrapper, using the same underlying mechanism, called CallAfter(). Especially if you use C++11, it's very simple to use as you can just pass it the code to be executed in the main thread directly, e.g.
void MyThreadCallback(void* data)
{
wxTheApp->CallAfter([=]() {
wxMessageBox("This is safe because we're in the main thread now");
// Do whatever you need to do with "data"
});
}
I created a thread using CreateThread() with standard function prototype
DWORD WINAPI func(LPVOID param);
When I call TForm's members sometimes it crashes with access violation.
I do not want use Embarcadero's TThread style functions, prefer to win32 std api.
What synchronize/other conditions I should met to successfully call TForm's or its descendants members?
Thanks
Calling VCL methods in threads other than the main thread is not supported.
You need to find a way to keep all your VCL access in the main thread. One commonly used technique is the Synchronize() method. You could also send windows messages since they will always be marshalled across to the thread that owns the window.
I imagine that it's the same in C++ Builder as it is in Delphi, but in Delphi it is preferable to call BeginThread() rather than CreateThread(). BeginThread() is a lightweight wrapper of CreateThread() but the main thing it does for you is to set the IsMultiThread global variable. If you do insist on calling CreateThread() then you must set IsMultiThread true first.
I want to make a simple worker thread inside a same class. However, there are 3 major problems that I am facing, which are:
Definition of a thread function in class header.
Thread function call.
Called thread function format.
I am also confused to use either AfxBeginThread or CreateThread function call to pass multiple thread parameters. Can anyone please provide me a simple worker thread to run in MFC based on the 3 things that I have provided above?
Definition of a thread function in class header: It has to be a static member because the usual way of putting "this" in a hidden parameter doesn't work. Since you only get one parameter, you want the parameter to be a pointer to a struct, and one member of the struct can be "this" of the class instance that your static member can call.
Thread function call: Since the function that gets called is going to use MFC, it is easiest to have the caller call AfxBeginThread. Since you say the thread will be a worker thread, call the version of AfxBeginThread that is designed for worker threads (even if it doesn't matter much).
Called thread function format. MSDN describes AfxBeginThread and says what prototype must be used for the first parameter.
Ideally, you should never be using CreateThred. And if you're using MFC, you MUST use AfxBeginThread to for creating threads.
I've given some explanation here in this discussion: http://www.daniweb.com/forums/thread249210.html
CreateThread is mainly for UI Threads but is still preferred to use the second method for AfxBeginThread. Store a reference to the threads handle in the header not the thread.
HANDLE hThread;
then in source start your thread pointing to your proc:
CWinThread *pThread;
if(!(pThread = AfxBeginThread(ThreadProc, NULL, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED))) {
delete arr;
}
::DuplicateHandle(GetCurrentProcess(), pThread->m_hThread, GetCurrentProcess(), &hThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
pThread->ResumeThread();
You start it suspended so you can copy the handle to the one you have stored in header. this way you can use the stored handle to check on exitcode.
I'm looking for the ability to spawn a thread or function so that it returns immediately to the calling line and continue on with the program but continues with the thread work.
For instance, if you call Form.ShowDialog(), it will create a modeless form that has its own UI thread.
Is there a way to do this (no form) without having to declare a TThread class? I guess sort of like an anonymous thread, if that even exists.
I don't know exactly why you don't want to create a TThread subclass, but if you are using the Windows version of C++ Builder you can use the _beginthreadex function (declared in process.h).
I'm writing a network library that a user can pass a function pointer to for execution on certain network events. In order to keep the listening loop from holding up the developer's application, I pass the event handler to a thread. Unfortunately, this creates a bit of a headache for handling things in a thread-safe manner. For instance, if the developer passes a function that makes calls to their Windows::Forms application's elements, then an InvalidOperationException will be thrown.
Are there any good strategies for handling thread safety?
Function pointers can not be thread safe as they declare a point to call. So they are just pointers.
Your code always runs in the thread it was called from (via the function pointer).
What you want to achieve is that your code runs in a specific thread (maybe the UI thread).
For this you must use some kind of queue to synchronize the invocation into the MainThread.
This is exactly what .Net's BeginInvoke()/Invoke() on a Form do. The queue is in that case (somewhere deep inside the .NET framework) the windows message queue.
But you can use any other queue as long as the "correct" thread reads and executes the call requests from that queue.