-1

マルチスレッドを利用するコードがありますが、それはWindowsを使用していますwxwdigetsのコードを変換したいです私は長い間試してきましたが、成功せず、最終的に私がしたことを削除し、ゼロから始めたいと思っています

#include "windows.h"
#include <iostream>
#include <stdio.h>


DWORD WINAPI ThreadFn(LPVOID vpParam);

int main() {
    using namespace std;

    // Create the thread and pass in the function pointer and counter
    unsigned int uiCounter = 0;
    DWORD qThreadID;
    HANDLE hThread = CreateThread(0, 0, ThreadFn, &uiCounter, 0, &qThreadID);

    // Loop until the user enters 'q'
    char cChar = ' ';
    while (cChar != 'q') {
        cout << uiCounter << endl;
        cChar = (char)getchar();
    }

    // Close the handle to the thread
    CloseHandle(hThread);

    return 0;
}


DWORD WINAPI ThreadFn(LPVOID vpParam)
{
    unsigned int& uirCounter = *((unsigned int*)vpParam);
    // Increment up to the maximum value
    while (uirCounter < 0xFFFFFFFF) {
        ++uirCounter;
    }
    return 0;
}
4

1 に答える 1

1

あなたが投稿したコードにはいくつかの重大な問題があります。さらに何かをする前に、それらを修正する必要があります。

  1. ワーカー スレッドは「ビジー ループ」です。利用可能なすべての CPU サイクルを消費し、GUI の実行など他の処理を不可能にし、応答を遅くします。簡単な修正として、Sleep() の呼び出しを while ループに追加することをお勧めします。

  2. メイン スレッドとワーカー スレッドの両方が同時にカウンター変数にアクセスしようとします。これを十分長く実行すると、クラッシュします。ミューテックスまたは同等のものでカウンターを保護する必要があります。

少し再設計して、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));
}
于 2012-08-02T11:47:03.680 に答える