2012-04-13 35 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)); 
}