あなたが投稿したコードにはいくつかの重大な問題があります。さらに何かをする前に、それらを修正する必要があります。
ワーカー スレッドは「ビジー ループ」です。利用可能なすべての CPU サイクルを消費し、GUI の実行など他の処理を不可能にし、応答を遅くします。簡単な修正として、Sleep() の呼び出しを while ループに追加することをお勧めします。
メイン スレッドとワーカー スレッドの両方が同時にカウンター変数にアクセスしようとします。これを十分長く実行すると、クラッシュします。ミューテックスまたは同等のものでカウンターを保護する必要があります。
少し再設計して、wxWidgets に移植しましょう。必要になります
A. カウンターを 1 秒間に 10 回 (約 ) インクリメントし、残りの時間はスリープして GUI を更新できるようにするワーカー スレッド
B. カウンター値を 1 秒に 2 回チェックして表示する GUI スレッド
C. GUI スレッドもキーボードを監視し、「q」が押されるとカウンターを停止します。
D. wxThreadHelperクラスを使用してスレッドを管理します。
主な実装の詳細は次のとおりです。
すべての wxThreadHelper の利点を含むメイン フレームを定義する
class MyFrame : public wxFrame, public wxThreadHelper
{
public:
MyFrame(const wxString& title);
// worker thread entry point
wxThread::ExitCode Entry();
// keyboard monitor
void OnChar(wxKeyEvent& event );
// display updater
void OnTimer(wxTimerEvent& event);
private:
// the counter
unsigned int mCounter;
// protect the counter from access by both threads at once
wxCriticalSection mCS;
// display update timer
wxTimer * mTimer;
DECLARE_EVENT_TABLE()
};
キーボードとタイマーのイベントに注意してください
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_CHAR(MyFrame::OnChar)
EVT_TIMER(-1,MyFrame::OnTimer)
END_EVENT_TABLE()
フレームを構築する
MyFrame::MyFrame(const wxString& title)
: wxFrame(NULL, wxID_ANY, title)
, mCounter( 0 )
{
// set the frame icon
SetIcon(wxICON(sample));
CreateStatusBar(2);
SetStatusText("Welcome to Asynchronous Counter!");
// Create thread and start it going
CreateThread();
GetThread()->Run();
// Create update timer and start it going
mTimer = new wxTimer(this);
mTimer->Start(500);
}
ワーカー スレッドはカウンターを 1 秒あたり 10 回インクリメントします
wxThread::ExitCode MyFrame::Entry()
{
// loop, so long as we haven't been asked to quit
while ( ! GetThread()->TestDestroy()) {
{
// increment counter, to a maximum value
wxCriticalSectionLocker lock( mCS );
if( mCounter >= 0xFFFFFFFF )
break;
++mCounter;
}
// Let other things happen for 1/10 second
Sleep(100);
}
// Counter is finished, or we have been asked to stop
return (wxThread::ExitCode)0;
}
キーボードの終了要求を監視する
void MyFrame::OnChar(wxKeyEvent& event )
{
event.Skip();
if( event.GetKeyCode() == (int) 'q' )
GetThread()->Delete();
}
タイマー起動時に表示を更新する
void MyFrame::OnTimer(wxTimerEvent& )
{
unsigned int current_counter_value;
{
wxCriticalSectionLocker lock( mCS );
current_counter_value = mCounter;
}
SetStatusText(wxString::Format("Counter = %d",current_counter_value));
}