Windows Threads ramble about interface threads and worker threads

Source: Internet
Author: User
Tags message queue

Each system is wired, and the most important role of the thread is parallel processing, which increases the concurrency rate of the software. For the interface, it can also improve the response force of the interface.

Threads are divided into interface threads and worker threads, and the interface is actually something that a thread draws, a thread that maintains a "message queue", and "Message Queuing" is the biggest difference between an interface thread and a worker thread, a word that should go into your head and be ingrained!

If it stops somewhere in the interface thread, it means it can't handle the window message, so sometimes we see the whole interface unresponsive. This problem will be followed by a function called Waitforobjectex to solve, we'll talk about later.

The thread first is its creation, which is created with the following function: CreateThread; Specific parameters I did not say, I check MSDN. The Thread1 is a thread function. The thread function is a global function, as follows:

DWORD WINAPI Thread1 (LPVOID lpparam)
{
while (1)
{
OutputDebugString ("11111");

Sleep (10);
}
return 0;
}

The following sentence is the creation of a thread
CreateThread (null, 0, Thread1, 0, 0, NULL);

Of course, we can not let a thread to fend for itself, it is possible to have some inexplicable problems when you exit the program, or to lose some data, or to play a crash dialog box and so on ...

So we're going to manage this thread, first of all, let it out.

We give it the while plus a BOOL variable g_bexitthread judgment, so that the thread function becomes the following:

DWORD WINAPI Thread1 (LPVOID lpparam)
{
while (! G_bexitthread)
{
OutputDebugString ("11111");

Sleep (10);
}
return 0;
}

Then set G_bexitthread to True when it's time to exit, say, "Hey, bro, you should quit."

Of course we also need to know if it's successful, because the thread handle is a kernel object, so we're going to use Windows WaitForSingleObject to wait. The code to create and wait for it to exit will change, with a HANDLE G_HTRD variable:

Create
G_bexitthread = FALSE;
G_HTRD = CreateThread (NULL, 0, Thread1, 0, 0, NULL);

Wait for thread to end
G_bexitthread = TRUE;

if (g_htrd! = NULL)
{
DWORD Dwret = WaitForSingleObject (G_HTRD, 5000);
if (Dwret = = wait_object_0)
{
AfxMessageBox ("Thread exit success!");
}
Else
{
DWORD dwret = 0;
GetExitCodeThread (G_HTRD, &dwret);
TerminateThread (G_HTRD, Dwret);
AfxMessageBox ("Thread exit, but not all ok!");
}
CloseHandle (G_HTRD);
G_HTRD = NULL;
}

It said that in the interface thread waiting for the end of another thread, that is, when using WaitForSingleObject will block the processing of the entire window message, so if we are in the interface thread to wait for other kernel objects, we have to use this "wait, handle the interface message" method. I have already written a Waitforobjectex function, as follows:

This function can only be used for interface threads
static DWORD Waitforobjectex (HANDLE Hhandle, DWORD dwmilliseconds)
{
BOOL BRet;
MSG msg;
INT Iwaitret;
int ntimeout = 0;
while ((BRet =:: GetMessage (&msg, NULL, 0, 0))! = 0)
{
if (ntimeout++ * >= dwmilliseconds)
Break

Iwaitret = WaitForSingleObject (Hhandle, 20);
if (Iwaitret! = wait_timeout)
{
Break
}
if (BRet = =-1)
{
Break
}
Else
{
:: TranslateMessage (&MSG);
::D ispatchmessage (&msg);
}
}

return iwaitret;
}

Many times, we don't want to use a thread as a global function, so this time we write the thread as a static member object of a class. Of course, there is no less than the two variables: Exit flag and thread handle. (Set this class is Ctestthreaddlg)

H file
BOOL M_bexitthread;
HANDLE M_HTRD;
Static DWORD WINAPI Thread1 (LPVOID lpparam);

CPP file, the this pointer is passed in when it is created, because the class static member function cannot access the non-static members of the class, there is no this pointer
(Knowledge points for C + +)
M_bexitthread = FALSE;
M_HTRD = CreateThread (null, 0, Thread1, this, 0, null);

The thread function becomes:

DWORD WINAPI ctestthreaddlg::thread1 (LPVOID lpparam)
{
Ctestthreaddlg *pdlg = (ctestthreaddlg*) Lpparam;
while (!pdlg->m_bexitthread)
{
OutputDebugString ("11111");

Sleep (10);
}
return 0;
}

When there are several lines Cheng start, we should pay attention to thread synchronization problem, thread synchronization in general, is the time when multiple threads share resources. For example, two threads all use the same vector, all the vector insert operation, unfortunately, vector is not thread-safe, this time the program will crash, so we have to synchronize the resources of vector, synchronous means "I visit when you wait." The procedure is generally as follows:

DWORD WINAPI ctestthreaddlg::thread1 (LPVOID lpparam)
{
Ctestthreaddlg *pdlg = (ctestthreaddlg*) Lpparam;
while (!pdlg->m_bexitthread)
{
OutputDebugString ("11111");

Pdlg->m_csforvec.lock ();
Pdlg->m_vectest.push_back ("111");
Pdlg->m_csforvec.unlock ();

Sleep (10);
}
return 0;
}

DWORD WINAPI ctestthreaddlg::thread2 (LPVOID lpparam)
{
Ctestthreaddlg *pdlg = (ctestthreaddlg*) Lpparam;
while (!PDLG->M_BEXITTHREAD2)
{
OutputDebugString ("222");

Pdlg->m_csforvec.lock ();
Pdlg->m_vectest.push_back ("222");
Pdlg->m_csforvec.unlock ();

Sleep (10);
}
return 0;
}

M_csforvec is a ccriticalsection variable, this synchronization object and other synchronization variables (events, semaphores, mutex, etc.) have some different, for example, only in the same process of access between the threads, the operating system user state access, the other must enter the nuclear mentality. So this leads to the core object of this critical area is about 100 times times faster than the others.

The above has said that the creation of threads, management (exit threads, waiting threads), synchronization, and so on, what we found common? As a programmer, we have to be very sensitive to discovering the commonality of these codes, which is the main premise of our code design.

First we find that the above thread has two variables:
BOOL M_bexitthread; Flags that let the thread exit
HANDLE M_HTRD; Thread handle

In addition we waitforsingleobject time can not wait indefinitely, so more than a DWORD m_dwwaittimeout;

Since I wanted to wrap the thread up and end, I designed these interfaces:

BOOL Start (LPVOID lpparam); Start thread, the parameters required by the thread are passed in from here
BOOL End (); End Thread
virtual void Run (); Rewrite the run function hovertree.com

So the entire thread is encapsulated into the following classes:

MyThread.h

#ifndef My_thread_h
#define My_thread_h

Class Cmythread
{
Public
Cmythread ();
Virtual ~cmythread ();

BOOL Start (LPVOID lpparam);
BOOL End ();
virtual void Run ();

Protected
Static DWORD WINAPI Thread (LPVOID lpparam);
void Runonceend ();

DWORD m_dwwaittimeout;
BOOL M_bexitthread;
HANDLE M_HTRD;
LPVOID M_lpparam;
};

#endif

MyThread.Cpp

#include "stdafx.h"
#include "MyThread.h"
/////////////////////////////////////////////////////////////////////////////
Cmythread
Cmythread::cmythread ()
{
M_bexitthread = FALSE;
M_HTRD = NULL;
M_dwwaittimeout = 5000;
}

Cmythread::~cmythread ()
{

}

BOOL Cmythread::start (LPVOID lpparam)
{
M_lpparam = Lpparam;
M_bexitthread = FALSE;
M_HTRD = CreateThread (null, 0, Thread, this, 0, NULL);

return TRUE;
}

BOOL Cmythread::end ()
{
M_bexitthread = TRUE;

if (m_htrd! = NULL)
{
DWORD Dwret = WaitForSingleObject (M_HTRD, m_dwwaittimeout);
if (Dwret = = wait_object_0)
{
AfxMessageBox ("Thread exit success!");
}
Else
{
DWORD dwret = 0;
GetExitCodeThread (M_HTRD, &dwret);
TerminateThread (M_HTRD, Dwret);
AfxMessageBox ("Thread fucking exit!");
}

CloseHandle (M_HTRD);
M_HTRD = NULL;
}

return TRUE;
}

DWORD WINAPI cmythread::thread (LPVOID lpparam)
{
Cmythread *PTRD = (Cmythread *) Lpparam;

while (!ptrd->m_bexitthread)
{
Ptrd->run ();
}

return 0;
}

void Cmythread::runonceend ()
{
M_bexitthread = TRUE;
CloseHandle (M_HTRD);
M_HTRD = NULL;
}

void Cmythread::run ()
{
}

When we need to write our own thread, we reload the run function.

Derive a class from what to ask
Class Cmythread1:public Cmythread
{
Public
virtual void Run ();
};

Rewrite the Run function
void Cmythread1::run ()
{
Ctestthreaddlg *pdlg = (Ctestthreaddlg *) M_lpparam;

OutputDebugString ("222");

Pdlg->m_csforvec.lock ();
Pdlg->m_vectest.push_back ("222");
Pdlg->m_csforvec.unlock ();

Sleep (10);

If this thread only wants to run once, add the following sentence
Runonceend ();
}

Then the use of our previous two threads becomes the following form:

CMyThread1 g_t1, G_t2, G_T3;
void Ctestthreaddlg::onbutton3 ()
{
G_t1. Start (this);
G_t2. Start (this);
G_t3. Start (this);
}

void Ctestthreaddlg::onbutton4 ()
{
G_t1. End ();
G_t2. End ();
G_t3. End ();
}

Only the following steps are required:
1. Derive your own thread class
2. Overloaded Run function
3. Call start to start the thread
4. Call end to end the thread

Of course, this package is my own favorite, the purpose of the package is easy to use, hide the details, you crossing can also be based on their own preferences, packaging thread use method, if you can open your results here, let me and everyone to learn about your design techniques, it is really very good and 3q!

http://www.cnblogs.com/roucheng/

Windows Threads ramble about interface threads and worker threads

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.