【问题标题】:Converting the code written in windows threads to wxwidgets threads将windows线程中编写的代码转换为wxwidgets线程
【发布时间】:2012-04-13 09:43:42
【问题描述】:

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

【问题讨论】:

  • 这里有具体问题吗?
  • 是的,我想在 wxwidgets 中执行相同的代码,我确实尝试了一些它一直崩溃的东西,所以我出于沮丧删除了它,我需要从头开始构建所有东西,所以需要建议/可能的答案
  • 你明白 wxWidgets 只是一个跨平台的 GUI 工具包吗?如果您的目标是其他平台,则必须找到其他线程选项。例如,OS X 现在提供 GCD,您拥有更底层的 POSIX 标准化线程(在 OS X、BSD、Linux 发行版上 - 需要付出一些努力 - 甚至在 Windows 上),甚至是 C 的新开发++11,其中包括线程设施。
  • 我没有针对除 windows 之外的任何其他东西,这些都是一件好事,但是我需要为这些东西使用 wxwidgets 线程。

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


【解决方案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));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 2020-02-07
    • 1970-01-01
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多