前言
最近忙着写项目,wxWidgets计划还有wxWidgets日志系统的拦截重定向,剩下一些比较杂的知识点,想到哪写到哪。比如进程间通信、调用外部程序后结束本程序(用于升级程序)、集成带窗口的ActiveX、创建单进程程序等,这些文档上基本都有。下面开始多线程的应用。
代码示例
废话不多说,此示例演示,子线程进程业务处理完之后通知主线程,等待主线程执行完,子线程接着处理业务的过程。
主要内容在主窗口文件和线程文件里面
主窗口头文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
#ifndef BLOG_WIDGETSMAIN_H #define BLOG_WIDGETSMAIN_H
#ifndef WX_PRECOMP #include <wx/wx.h> #endif
#include "blog_WidgetsApp.h" enum SIGN_NUM{ SIGN_1 = 8000, BTN1, BTN2 };
class blog_WidgetsFrame: public wxFrame { public: blog_WidgetsFrame(){} blog_WidgetsFrame(wxFrame *frame, const wxString& title); ~blog_WidgetsFrame(); public: wxMutex* mutex; wxCondition* condition; wxString speak; protected: void OnThreadEvent(wxThreadEvent& event); void OnBtnStartEvent(wxCommandEvent& event); void OnBtnChildrenEvent(wxCommandEvent& event); void SendSign(); private: DECLARE_DYNAMIC_CLASS(blog_WidgetsFrame); DECLARE_EVENT_TABLE()
};
#endif
|
主窗口实现文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
#include "blog_WidgetsMain.h" #include "ChildrenThread.h"
IMPLEMENT_DYNAMIC_CLASS(blog_WidgetsFrame,wxFrame) BEGIN_EVENT_TABLE(blog_WidgetsFrame, wxFrame)
EVT_THREAD(SIGN_1,blog_WidgetsFrame::OnThreadEvent) EVT_BUTTON(BTN1,blog_WidgetsFrame::OnBtnStartEvent) EVT_BUTTON(BTN2,blog_WidgetsFrame::OnBtnChildrenEvent) END_EVENT_TABLE()
blog_WidgetsFrame::blog_WidgetsFrame(wxFrame *frame, const wxString& title) : wxFrame(frame, -1, title) { mutex = new wxMutex(); condition = new wxCondition(*mutex);
wxButton* button1 = new wxButton(this,BTN1,wxT("开始")); wxButton* button2 = new wxButton(this,BTN2,wxT("通知子线程")); wxBoxSizer* box = new wxBoxSizer(wxVERTICAL); box->Add(button1,1,wxALL,0); box->Add(button2,1,wxALL,0); this->SetSizer(box); }
blog_WidgetsFrame::~blog_WidgetsFrame() { if(condition) { delete condition; condition = NULL; } if(mutex) { delete mutex; mutex = NULL; } } void blog_WidgetsFrame::OnThreadEvent(wxThreadEvent& event) { wxString text = event.GetString(); wxMessageBox(text,wxT("子线程")); }
void blog_WidgetsFrame::OnBtnStartEvent(wxCommandEvent& event) { ChildrenThread* childrenThread = new ChildrenThread(this); if(childrenThread != NULL) { if(childrenThread->Create()== wxTHREAD_NO_ERROR) { childrenThread->Run(); } } } void blog_WidgetsFrame::OnBtnChildrenEvent(wxCommandEvent& event) { SendSign(); }
void blog_WidgetsFrame::SendSign() { wxMutexLocker lock(*mutex); condition->Signal(); }
|
子线程头文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #ifndef CHILDRENTHREAD_H #define CHILDRENTHREAD_H
#include <wx/wx.h> #include "../blog_WidgetsMain.h" class ChildrenThread: public wxThread { public: ChildrenThread(wxFrame* frame); virtual ~ChildrenThread(); virtual void* Entry(); void threadWait(wxThreadEvent& event); protected:
private: wxFrame* m_frame; };
#endif
|
子线程实现文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include "ChildrenThread.h"
ChildrenThread::ChildrenThread(wxFrame* frame):wxThread(wxTHREAD_DETACHED) { m_frame = frame; } ChildrenThread::~ChildrenThread() {
} void* ChildrenThread::Entry() { blog_WidgetsFrame* frame = wxDynamicCast(m_frame,blog_WidgetsFrame); if(frame) { frame->mutex->Lock(); wxThreadEvent evt1(wxEVT_COMMAND_THREAD,SIGN_1); evt1.SetString(wxT("子线程第一次执行的结果通知")); threadWait(evt1);
wxThreadEvent evt2(wxEVT_COMMAND_THREAD,SIGN_1); evt2.SetString(wxT("子线程第二次执行的结果通知")); frame->GetEventHandler()->QueueEvent(evt2.Clone());
frame->mutex->Unlock(); } return NULL; } void ChildrenThread::threadWait(wxThreadEvent& event) { blog_WidgetsFrame* frame = wxDynamicCast(m_frame,blog_WidgetsFrame); frame->GetEventHandler()->QueueEvent(event.Clone()); frame->condition->Wait();
}
|
调用文件就不贴出来了,简单的父子线程协同工作的demo完成。
结尾
下一篇应该是wxWidgets的日志系统的拦截和重定向,把产生的日志全部拦截,记录到数据库中,供排查错误使用。