-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)变得缓慢且无响应。我建议在 while 循环中添加对 Sleep() 的调用,作为快速修复。

  2. 主线程和工作线程都尝试同时访问计数器变量。你运行这个足够长的时间,它会崩溃。您应该使用互斥锁或等效物保护计数器。

让我们稍微重新设计一下,然后移植到 wxWidgets。我们会需要

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

B. 每秒检查和显示计数器值两次的 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);
}

工作线程每秒递增计数器 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 回答