1. Start a thread with a C + + object
Q: How to use a C + + member function as the starting function for a thread.
Examples of errors
#include <windows.h> #include <stdio.h> #include <process.h> typedef unsigned (WINAPI *pbeginthreadex
_threadfunc) (LPVOID lpthreadparameter);
typedef unsigned *PBEGINTHREADEX_THREADID;
Class Threadobject {public:threadobject ();
void Startthread ();
Virtual DWORD winapi ThreadFunc (lpvoid param);
void WaitForExit ();
Private:handle M_hthread;
DWORD M_threadid;
};
Threadobject::threadobject () {m_hthread = NULL;
M_threadid = 0;
} void Threadobject::startthread () {m_hthread = (HANDLE) _beginthreadex (NULL, 0, (Pbeginthreadex_threadfunc) ThreadFunc, 0, 0, (Pbeginthreadex_thre
Adid) &m_threadid);
if (m_hthread) {printf ("Thread launched\n");
} void Threadobject::waitforexit () {WaitForSingleObject (M_hthread, INFINITE);
CloseHandle (M_hthread); } DWORD WINAPI Threadobject::threadfunc (LPVOID param)//to the member function of a class by default there is a This parameter {//do something useful ... return 0;
void Main () {Threadobject obj; Obj.
Startthread (); Obj.
WaitForExit ();
}
The right approach
To start a thread with a member function, either use a static member function or use a C function instead of a C + + member function. Both of these
The essence of technology is the same, but one advantage of static member functions is that it can handle class private member variables and protected
The member variable.
Starts a thread instance by a member function:
#define Win32_lean_and_mean #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <
process.h> typedef unsigned (WINAPI *pbeginthreadex_threadfunc) (LPVOID lpthreadparameter);
typedef unsigned *PBEGINTHREADEX_THREADID; This threadobject was created by a thread//then wants to start another thread. All//public member functions except THREADFUNC ()//are called through that original thread.
The//virtual function Threadmemberfunc () is//the start of the new thread.
Class Threadobject {public:threadobject ();
void Startthread ();
void WaitForExit ();
Static DWORD winapi ThreadFunc (lpvoid param);
Protected:virtual DWORD Threadmemberfunc ();
HANDLE M_hthread;
DWORD M_threadid;
};
Threadobject::threadobject () {m_hthread = NULL;
M_threadid = 0; } void Threadobject::startthread () {m_hthread = (HANDLE) _beginthreadex (NULL, 0, Pbeginthreadex_thr Eadfunc) threadobject::tHreadfunc, (LPVOID) This, 0, (Pbeginthreadex_threadid) &m_threadid);
if (m_hthread) {printf ("Thread launched\n");
} void Threadobject::waitforexit () {WaitForSingleObject (M_hthread, INFINITE);
CloseHandle (M_hthread); }////This are a static member function. Unlike//C static functions, you are place the static//Declaration on the function declaration in the//class
its implementation.
Static member functions have no ' this ' pointer,//But do have access rights. DWORD winapi Threadobject::threadfunc (lpvoid param) {//Use the Param as the address of the object Threadobjec
t* PTO = (threadobject*) param; Call to the member function.
Since we have a//proper object pointer, even virtual functions/would be called properly.
return Pto->threadmemberfunc ();
The////This above function threadobject::threadfunc ()//calls this function is on the thread starts up. DWORD ThreadobjEct::threadmemberfunc () {//do something useful ... return 0;}
void Main () {Threadobject obj; Obj.
Startthread (); Obj.
WaitForExit ();
How to use constructors and destructors to write a more secure multithreaded program in C + +, and how to make an interchangeable locking mechanism using virtual functions and polymorphic properties. Encapsulates a critical section class CriticalSection {public:criticalsection () in C + +, ~criticalsection (); void Enter (); void Leave
();
Private:critical_section M_critsect;
} criticalsection::criticalsection () {initializecriticalsection (&m_critsect);}
Criticalsection::~criticalsection () {deletecriticalsection (&m_critsect);}
Criticalsection::enter () {entercriticalsection (&m_critsect);}
Criticalsection::leave () {leavecriticalsection (&m_critsect);}
Using the CriticalSection class class string {public:string () in the String class;
Virtual ~string ();
virtual void Set (char *str);
int GetLength ();
Private:criticalsection M_sync;
char * M_PDATA;
};
String::string () {m_pdata=null;} String::~string () {m_sync.enter (); delete []m_pdata; M_sync.leave ();
} void String::set (char *str) {m_sync.enter (); delete [] m_pdata; m_pdata=new char[::strlen (str) +1];:: strcpy (M_pdata,
STR);
M_sync.leave (); int String::getlength () {if (m_pdata==null) return 0; M_sync.enter (); int Len=::strlen (m_pdata); M_sync.leave (); retur
n Len; }
This allows you to declare a string variable, and you can get a sync effect without knowing the critical section.
----Establish an abstract synchronization object
Class lock
{public
:
Lock (CriticalSection *pcritsect);
~lock ();
Private:
criticalsection *m_pcritical;
Lock::lock (criticalsection *pcritsect)
{
m_pcritical=pcritsect;
EnterCriticalSection (&m_pcritical);
}
Lock::~lock ()
{
leavecriticalsection (&m_pcritical);
}
This destructor can be invoked automatically, and the critical section is automatically unlocked. Will never forget to critical
Section unlocked.
-------to create interchangeable lock
Class Lockableobject
{public
:
lockableobject () {}
Virtual ~ lockableobject () {}
virtual void Lock () =0;
virtual void UnLock () =0;
Public Criticalsectionv2:public lockableobject
{
CriticalSectionV2 ();
Virtual ~criticalsectionv2 ();
virtual void Lock ();
virtual void UnLock ();
Private:
critical_section m_critsect;
Criticalsectionv2::criticalsectionv2 ()
{
initializecriticalsection (&m_critsect);
}
Criticalsectionv2::~criticalsectionv2 ()
{
deletecriticalsection (&m_critsect);
}
Criticalsectionv2::lock ()
{
entercriticalsection (&m_critsect);
}
Criticalsectionv2::unlock ()
{
leavecriticalsection (&m_critsect);
}
Create a very safe and simple lock
class LockV2
{public
:
LockV2 (Lockableobject *plockable);
~lockv2 ();
Private:
lockableobject * m_plockable;
Lockv2::lockv2 (Lockableobject *plockable)
{
m_plockable=plockable;
M_plockable->lock ();
}
Lockv2::~lockv2 ()
{
m_plockable->unlock ();
}
A direct call to replace the Win32 API with the C + + class above
Rewrite the string class with secure and simple "Lock"
Class StringV2
{public
:
StringV2 ();
Virtual ~stringv2 ();
virtual void Set (char * str);
int GetLength ();
Private:
CriticalSectionV2 m_lockable;
char * m_pdata;
};
Stringv2::stringv2 ()
{
m_pdata=null;
}
Stringv2::~stringv2 ()
{
Delete [] m_pdata
}
void Stringv2::set (char *str)
{
LockV2 locallock (&m_lockable);
delete [] m_pdata;
M_pdata=null;
M_pdata=new Char[strlen (str) +1];
strcpy (M_PDATA,STR);
}
int String::getlength ()
{
LockV2 locallock (&m_lockable);
if (m_pdata==null) return
0;
Return:: strlen (m_pdata);
Copy Search Replication Search