A simple thread class

xiaoxiao2021-03-06  18

When there is a lot, we all need such a thread class to manage our thread.

I am now the simplest thread management class.

Our thread will of course start a thread. And it will let users write a thread handler to add to my class.

So this will read a function pointer to a handler from the outside to me.

When you write this handler, you will need an entry parameter. Here I design to use a void * type to pass.

This is better. Because all this variable can pass all types. Use pointers all can be transmitted into this type.

At this time we can solve this class how to interface with the outside.

Then how do we manage this thread on, work, and exit?

Use two EVENT objects.

A event is to manage this thread is to work, and one is whether the thread is turned off.

in conclusion. The members variables that this class may need are:

PFUN M_PFN; // Function Pointer

Void * m_pparam; // parameter

Handle M_Eventarr [2]; // Two Waiting Events

Member function

CThreadManager (PFUN _PFUN, VOID * _PPARAM); // Constructor

Void start (); // Turn on thread

Void work (); // Start work

Void Close (); // It will close this thread

~ Cthreadmanager (); //

Static DWORD WORKPROCESS (VOID * _PARAM); // Thread function in the thread management class

This gives a class of such a class.

// ThreadManager.h: interface for the cthreadmanager class.////

#if! defined (AFX_THREADMANAGER_H__C22364D8_F0DE_4391_B4E3_8DA3A1B720DB__InCluded_) # define afx_threadmanager_h__c22364d8_f0de_4391_b4e3_8da3a1b720db__included_

#if _msc_ver> 1000 # pragma overce # endif ///_msc_ver> 1000 # include "wtypes.h" #include #include "winbase.h" Using Namespace std;

TYPEDEF long (* _PARAM); typedef vector handlearr; typef vector Intarr;

Const int threadmanager_userless = (unsigned int) -1; // thread management class class cthreadManager {public: cthreadManager (pfun _pfun, void * _pparam); cthreadManager (); virtual ~ cthreadmanager ();

// Interface function void beginprocess (); // Turn on thread void notifyProcess (); // Start working void exitprocess (); // It will turn this thread to the Virtual Int RewriteFun (); // Overloaded function

protected: int m_nWaitTime; int m_nThreadNo; PFUN m_pFn; void * m_pParam; HANDLE m_eventArr [2]; HANDLE m_eventExit; HANDLE m_eventWoked; static DWORD WINAPI WorkProcess (void * _param); static DWORD WINAPI WorkProcessEx (void * _param); void InitParam ( };

#ndif //! defined (AFX_THREADMANAGER_H__C22364D8_F0DE_4391_B4E3_8DA3A1B720DB__INCLUDED _) // ThreadManager.cpp: Implementation of the cthreadmanager class.////

#include "stdafx.h" #include "threadManager.h"

//// construction / destruction //

CThreadManager :: CThreadManager (PFUN _pFun, void * _pParam) {m_pFn = _pFun; m_pParam = _pParam; m_nWaitTime = THREADMANAGER_USERLESS; InitParam ();} CThreadManager :: CThreadManager () {m_pFn = NULL; m_pParam = NULL;

INTPARAM ();} int cthreadmanager :: shutritefun () {return 0;}

CthreadManager :: ~ cthreadManager () {EXIXTPROCESS (); CloseHandle (M_Eventarr [0]); CloseHandle (M_Eventarr [1]); CloseHandle (M_EventExit); CloseHandle (M_Eventwoked);

}

void CThreadManager :: InitParam () {m_nWaitTime = THREADMANAGER_USERLESS; m_eventArr [0] = :: CreateEvent (NULL, FALSE, FALSE, NULL); m_eventArr [1] = :: CreateEvent (NULL, FALSE, FALSE, NULL); m_eventExit = :: CreateEvent (Null, True, False, Null); M_Eventwoked = :: CreateEvent (null, false, false, null);} void cthreadManager :: beginprocess () {DWORD DWID; handle htemp; if (m_pfn == null) {Htemp = :: CreateThread (Null, 0, WorkProcessEx, this, null, & dwid);} else {htemp = :: CreateThread (Null, 0, WorkProcess, this, null, & dwid);} :: closehandle (htemp); }

Void CthreadManager :: NotifyProcess () {:: setEvent (m_eventarr [1]); :: waitforsingleObject (m_eventwoked, infinite);}

Void CthreadManager :: EXITPROCESS () {:: setEvent (m_eventarr [0]) ;: waitforsingleObject (m_eventexit, infinite);}

DWORD CThreadManager :: WorkProcess (void * _param) {CThreadManager * pObj = (CThreadManager *) _ param; DWORD dwRet = -1; while (1) {dwRet = :: WaitForMultipleObjects (2, pObj-> m_eventArr, FALSE, INFINITE); IF (dwret- = Wait_Object_0; if (dwret == 0) goto exit; else {:: setEvent (pobj-> m_eventwoked); if ((* pobj-> m_pfn) (pobj-> m_pparam) ) == - 1) {goto exit;

}}} Exit: :: setEvent (pobj-> m_eventexit); return 0;}

DWORD CThreadManager :: WorkProcessEx (void * _param) {CThreadManager * pObj = (CThreadManager *) _ param; DWORD dwRet = -1; while (1) {dwRet = :: WaitForMultipleObjects (2, pObj-> m_eventArr, FALSE, INFINITE); IF (dwret- = Wait_Object_0; if (dwret == 0) goto exit1; else {:: setEvent (pobj-> m_eventwoked); if (Pobj-> REWRITEFUN () == - 1) { Goto exit1;}}} exit1: :: setEvent (pobj-> m_eventexit); Return 0;

This is a very simple single-thread management class. If you want to change this class into a thread pool, it is more simple.

Just make the event of this work to an automatic RESET mode, and this exit event is set to

Do not use Auto RESET. This difference can only be used once if you use it.

Also add a number of threads in the Start function. This will initially come out of a thread pool object.

But there are some problems in this way.

How to do it when you quit our thread.

It can be seen here. We just set an event. The function in this thread has encountered this incident.

Will be returned, this will have a problem. If our thread has not been processed, this setting is called outside the class.

Event function. Of course, it will not wait. Some of the external objects began to destructure. May current thread processing function

The this pointer to the outside of an object will be used. It can be imagined, so it will make the program to collapse.

There is one solution to the solution. In this exit function, you must wait for an event, which is the completion of this thread.

The event gives Set. This will ensure that our call exit function. Our thread must be returned.

This will also come to new problems. That is, when an external incoming function, the exit function of this thread management class may be called.

This will have a problem of deadlocks.

For example: A class, I wrote a handset, add a thread class as a member variable, in this handler, the parameters I use are

The THIS pointer in Class A. There is such a sentence in the process of processing: pobj-> m_threadmanager-> close (); this time, if there is this need, we can define a return value of a handset to determine our thread class. Not to put

This thread exits. That is, don't use the already on the way, but directly use Return -1; then in our thread management class

Write a condition in the While If the function pointer returns to -1, I will have to quit all threads! This is basically possible as a class.

I have modified some questions before. 1. Increase a virtual function that can be inherited directly; 2. Add a wait event for the NotifyProcess function, which may ensure that the thread will work once after the NotifyProcess call.

转载请注明原文地址:https://www.9cbs.com/read-41090.html

New Post(0)