将用Windows口程编写的代码转换为wxwidgets线程

时间:2012-04-13 09:43:43

标签: c++ multithreading winapi thread-safety wxwidgets

我有使用多线程的代码,但它是通过使用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;
}

1 个答案:

答案 0 :(得分:0)

您发布的代码存在一些严重问题。在你做更多的事情之前,他们需要修复。

  1. 工作线程是一个“忙循环”。它将消耗所有可用的CPU周期并进行其他任何操作,例如运行GUI,不可能缓慢且无响应。我建议在while循环中添加对Sleep()的调用,作为快速修复。

  2. 主线程和工作线程都试图同时访问计数器变量。你运行这么久就会崩溃。您应该使用互斥锁或同等产品来保护计数器。

  3. 让我们做一些轻微的重新设计,然后移植到wxWidgets。我们需要

    一个。一个工作线程,它使计数器每秒递增十次(大约)并在其余时间休眠,以便我们可以更新GUI

    B中。一个GUI线程,每秒检查并显示两次计数器值

    ℃。如果按下“q”,GUI线程也将监视键盘并停止计数器。

    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);
    }
    

    工作线程每秒递增计数器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));
    }