Okay, i will look for "Create()" i the example...doublemax wrote: ↑Fri Feb 14, 2020 1:33 amThe Create() is missing (unless you put that into the thread ctor). The whole creation and starting of a thread is a 3-step process.in between. That crashesCode: Select all
new clsParserThread(Parser,Code))->Run();
Code: Select all
clsParserThread *thread = new clsParserThread(Parser,Code); if( thread->Create() == wxTHREAD_NO_ERROR ) thread->Run();
wxThread / newbie Topic is solved
-
- Earned some good credits
- Posts: 147
- Joined: Mon Sep 01, 2014 10:14 am
Re: wxThread / newbie
Re: wxThread / newbie
If several of your tasks will be appear after running of first task - you need worker pool. Unfortunately there isn't worker pool in wxWidgets though corresponding ticket are open for years - wxThreadPool class for multi-threaded job management.art-ganseforth wrote: ↑Fri Feb 14, 2020 2:13 am This structure seems to be simelar to the multithreading-structure (one main-script calling several independent sub-scripts to be started at one 'entry-point'). The question is, how to implement it...
If there are not many tasks you can run each of them in own thread or use parallel for (once again wxWidgets don't provide this feature but there are many libraries and of course parallel execution algorithms from C++17)
-
- Earned some good credits
- Posts: 147
- Joined: Mon Sep 01, 2014 10:14 am
Re: wxThread / newbie
Okay...
I think i have what i want. I wrote a very small class derived from wxThreadHelper.
Here is the code:
I've not not yet, if the threads are really distributed to different CPU-cores, but i hope so (i don't see any reason, why not).
Best,
Frank
Supplement:
I will implement this in my project and (if i don't forget it) i'll report the result here...
I think i have what i want. I wrote a very small class derived from wxThreadHelper.
Here is the code:
Code: Select all
/////////////////////////////////////////////////////////////////////////////////////////////
// Test-application to see id and how two
// wxThreadHelper-instances work parallel
/////////////////////////////////////////////////////////////////////////////////////////////
#define wxUSE_THREADS 1
#include <wx/wx.h>
// --- Standard class-declarations --------------------
class clsApp : public wxApp {
virtual bool OnInit();
};
IMPLEMENT_APP(clsApp) ;
class clsFrame : public wxFrame {
public:
clsFrame();
void OnClose(wxEvent &ev);
wxTextCtrl *textCtrl;
};
// --- Globals ----------------------------------------
wxTimer *timer = NULL;
clsFrame *mainWin = NULL;
int idCT = 0;
/////////////////////////////////////////////////////////////////////////////////////////////
// The thread-class (declaration and implementation)
/////////////////////////////////////////////////////////////////////////////////////////////
class clsThread : public wxThreadHelper, public wxEvtHandler {
public:
clsThread();
virtual void DoJob (); // Initiate a job without timer
virtual void OnDoJob (wxEvent &ev); // Initiate jobs the global timer
virtual void OnInternalTimer (wxEvent &ev); // This timer is needed, to execute jobs parallel.
virtual wxThread::ExitCode Entry ();
wxTimer pTimer;
int ct = 0;
int id = -1;
};
clsThread :: clsThread() : wxThreadHelper(), wxEvtHandler() {
pTimer.Connect (wxEVT_TIMER, wxEventHandler(clsThread::OnInternalTimer), NULL, this);
if (CreateThread() == wxTHREAD_NO_ERROR ) GetThread()->Run(); else wxMessageBox("error");
};
wxThread::ExitCode clsThread::Entry() { id = idCT++;
// As an example, i connect both threads to the timer, but the second one with some delay.
// Also the first thread ist disconnected after 10 secondas.
if ( id) Sleep(2000); timer->Connect (wxEVT_TIMER, wxEventHandler(clsThread::OnDoJob), NULL, this);
if (!id) { Sleep(10000); timer->Disconnect (wxEVT_TIMER, wxEventHandler(clsThread::OnDoJob), NULL, this); }
while(1) Sleep(10000); // Endless loop - the 'job' is done in the OnTimer-function below
// --- Old version with TestDestroy() ---
//while (!GetThread()->TestDestroy()) Sleep(100); // Endless loop - the 'job' is done in the OnTimer-function below
//return NULL;
}
void clsThread :: OnDoJob(wxEvent &ev) { ev.Skip(); DoJob(); };
void clsThread :: DoJob() {
pTimer.Start (0, wxTIMER_ONE_SHOT); // By using a second timer, this function returns immideately.
};
void clsThread :: OnInternalTimer(wxEvent &ev) {
// Do the job here. I used a simple id to decide what to do, but you probably may derive
// classes with different OnInternalTimer-functions.
if ( id) { Sleep(300); mainWin->textCtrl->AppendText(wxString::Format("Thread-id: %d - Jobs done: %d\n", id, ++ct)); }
else { mainWin->textCtrl->AppendText(wxString::Format("Thread-id: %d - Jobs done: %d\n", id, ++ct)); }
}
/////////////////////////////////////////////////////////////////////////////////////////////
// End of the thread-class. Nothing more is needed
/////////////////////////////////////////////////////////////////////////////////////////////
// --- Standard class-implementations -----------------
bool clsApp::OnInit() {
if (!wxApp::OnInit()) return false;
timer = new wxTimer(); timer->Start(1000);
SetTopWindow(new clsFrame());
// For demonstration, on sub-thread is started here and a jom is initiated.
// The other in clsFrame:: clsFrame() below.
(new clsThread())->DoJob();
return true;
}
clsFrame:: clsFrame() : wxFrame(NULL, -1, "", wxPoint(250, 150), wxSize(500, 300) ) {
mainWin = this;
textCtrl = new wxTextCtrl(this, -1, "", wxPoint(0,0), wxDefaultSize, wxTE_MULTILINE);
Connect (wxEVT_CLOSE_WINDOW, wxEventHandler(clsFrame::OnClose), NULL, this);
Show(true);
// The first sub-thread is started here. The other one in clsApp::OnInit() above.
clsThread *tmp = new clsThread();
// Initiate a job for this thread. Both threads have an output, even if they are started
// almost at the same time.
tmp->DoJob();
// ...but there is no cue inside of the thread. Therefore this one overwritses the line
// before. Otherwise the job-counter would be incremented by two.
// However: Calling a thread twice, does not crash the program.
tmp->DoJob();
}
void clsFrame:: OnClose(wxEvent &ev) { delete timer; ev.Skip(); }
Best,
Frank
Supplement:
I will implement this in my project and (if i don't forget it) i'll report the result here...
Re: wxThread / newbie
Sorry, this will not work as you expect, event handlers (in this case your timer event handlers) are always called in the context of the main thread.
Use the source, Luke!
-
- Earned some good credits
- Posts: 147
- Joined: Mon Sep 01, 2014 10:14 am
Re: wxThread / newbie
On my system, the posted code worked as it is. But for my application i don't even need to initiate the threads by a global timer.
I've already a version that doesn't crash my application (but i have to implement a sync-technic). This new version is a fire-and-forget one. I call it with with a char* that refers the code to be executed, and with a pointer to the interpreter-instance, that should interpret it (a subinstance of the calling one). After execution the Interpreter returns to the calling clsTask-instance, so it can delete itself by calling delete this.
And the best: All CPU-cores are in use...
I've already a version that doesn't crash my application (but i have to implement a sync-technic). This new version is a fire-and-forget one. I call it with with a char* that refers the code to be executed, and with a pointer to the interpreter-instance, that should interpret it (a subinstance of the calling one). After execution the Interpreter returns to the calling clsTask-instance, so it can delete itself by calling delete this.
And the best: All CPU-cores are in use...