wxThread

wxThread 知识点整理


. wxThread Type


There are two types of threads in wxWidgets: detached and joinable.By default wxThreads in wxWidgets use the detached behavior.

Detached threads delete themselves once they have completed, either by themselves when they complete processing or through a call to Delete(), and thus must be created on the heap (through the new operator, for example).

Joinable threads do not delete themselves when they are done processing and as such are safe to create on the stack. Joinable threads also provide the ability for one to get value it returned from Entry() through Wait(). you must Wait() for a joinable thread or the system resources used by it will never be freed, and you also must delete the corresponding wxThread object yourself if you did not create it on the stack.

Don't create global thread objects because they allocate memory in their constructor, which will cause problems for the memory checking system.


. wxThread Deletion

Since detached threads delete themselves when they are finished processing, you should take care when calling a routine on one. If you are certain the thread is still running and would like to end it, you may call Delete() to gracefully end it (which implies that the thread will be deleted after that call to Delete()). It should be implied that you should never attempt to delete a detached thread with the delete operator or similar means.

    // it's better to do any thread cleanup in the OnClose()
    // event handler, rather than in the destructor.
    // This is because the event loop for a top-level window is not
    // active anymore when its destructor is called and if the thread
    // sends events when ending, they won't be processed unless
    // you ended the thread from OnClose.

    class MyThread : public wxThread
    {
    public:
        MyThread(MyFrame *handler)
            : wxThread(wxTHREAD_DETACHED)
            { m_pHandler = handler }
        ~MyThread();

    protected:
        virtual ExitCode Entry();
        MyFrame *m_pHandler;
    };

    ...

    m_pThread = new MyThread(this);

    if (m_pThread->Create() != wxTHREAD_NO_ERROR || m_pThread->Run() != wxTHREAD_NO_ERROR)
    {
            wxLogError("Can't create the thread!");
            delete m_pThread;
            m_pThread = NULL;
    }
    else
    { 
    // after the call to wxThread::Run(), the m_pThread pointer is "unsafe":
    // at any moment the thread may cease to exist (because it completes its work).
    }


Regardless of whether it has terminated or not, you should call Wait() on a joinable thread to release its memory. If you created a joinable thread on the heap, remember to delete it manually with the delete operator or similar means.

As mentioned, Wait() or Delete() functions attempt to gracefully terminate a joinable and a detached thread, respectively. They do this by waiting until the thread in question calls TestDestroy() or ends processing (i.e. returns from wxThread::Entry).

Obviously, if the thread does call TestDestroy() and does not end, the thread which called Wait() or Delete() will come to halt. This is why it's important to call TestDestroy() in the Entry() routine of your threads as often as possible and immediately exit when it returns true.


. wxWidgets Calls in Secondary Threads

All threads other than the "main application thread" (the one running wxApp::OnInit() or the one your main function runs in, for example) are considered "secondary threads". These include all threads created by Create() or the corresponding constructors.
GUI calls, such as those to a wxWindow or wxBitmap are explicitly not safe at all in secondary threads and could end your application prematurely. This is due to several reasons, including the underlying native API and the fact that wxThread does not run a GUI event loop similar to other APIs as MFC.

A workaround for some wxWidgets ports is calling wxMutexGUIEnter() before any GUI calls and then calling wxMutexGUILeave() afterwords. However, the recommended way is to simply process the GUI calls in the main thread through an event that is posted by wxQueueEvent(). This does not imply that calls to these classes are thread-safe, however, as most wxWidgets classes are not thread-safe, including wxString.


. Don't Poll a wxThread

A common problem users experience with wxThread is that in their main thread they will check the thread every now and then to see if it has ended through IsRunning(), only to find that their application has run into problems because the thread is using the default behavior (i.e. it's detached) and has already deleted itself. Naturally, they instead attempt to use joinable threads in place of the previous behavior. However, polling a wxThread for when it has ended is in general a bad idea - in fact calling a routine on any running wxThread should be avoided if possible. Instead, find a way to notify yourself when the thread has ended.
Usually you only need to notify the main thread, in which case you can post an event to it via wxQueueEvent(). In the case of secondary threads you can call a routine of another class when the thread is about to complete processing and/or set the value of a variable, possibly using mutexes (see wxMutex) and/or other synchronization means if necessary.



void wxMutexGuiEnter()
void wxMutexGuiLeave()
This function must be called when any thread other than the main GUI thread wants to get access to the GUI library.


wxSleep() can't be called from non-GUI thread! wxThread::Sleep()


void wxPostEvent(wxEvtHandler *dest, wxEvent& event)

In a GUI application, this function posts event to the specified dest object using wxEvtHandler::AddPendingEvent. Otherwise, it dispatches event immediately using wxEvtHandler::ProcessEvent. See the respective documentation for details (and caveats).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值