2012-04-13 23 views
-1

我有使用多线程的代码,但它是通过使用Windows我想转换wxwdigets中的代码我一直在尝试很长时间,但没有成功,最终我删除了我所做的,并希望从头开始转换在windows线程中写入的代码到wxwidgets线程

#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; 
} 
+2

是否有一个具体的问题在这里? – 2012-04-13 09:44:59

+0

是的,我想在wxwidgets中做相同的代码,我尝试了一些保持崩溃的东西,所以我把它从挫折中删除了,我需要从头开始构建所有东西,所以需要建议/ possibleanswers – 2012-04-13 09:46:59

+0

你明白wxWidgets只是一个十字平台GUI工具包?如果你的目标是其他平台,你将不得不寻找其他的线程选项。例如,OS X现在提供GCD,您已经拥有更低级别的POSIX标准化线程(在OS X,BSD,Linux发行版上 - 即使在Windows上也要付出一点努力),甚至使用C++ 11其中包括线程设施。 – 2012-04-13 09:53:31

回答

0

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

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

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

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

A.工作线程该计数器加一十次秒(约)和休眠的时间休息,所以我们可以更新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); 
} 

工作线程的增量对抗每秒

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; 

} 

监控键盘10次退出请求

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