//
// Use the reference count during a long thread process
// Cheungmine
//
# Include <assert. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <windows. h>
# Include <process. h>
// It shoshould be used if the worker class will use CRT Functions
Static handle crtcreatethread (lpsecurity_attributes lpsa,
DWORD dwstacksize,
Lpthread_start_routine pfnthreadproc,
Lpvoid pvparam,
DWORD dwcreationflags,
Lpdword pdwthreadid)
{
// _ Beginthreadex CILS createthread which will set the last error value before it returns
Return (handle) _ beginthreadex (lpsa,
Dwstacksize,
(Unsigned int (_ stdcall *) (void *) pfnthreadproc,
Pvparam,
Dwcreationflags,
(Unsigned int *) pdwthreadid );
}
Class cuserdata
{
Public:
Cuserdata (): m_data (100)
{
Printf ("cuserdata ()/n ");
}
~ Cuserdata ()
{
Printf ("~ Cuserdata ()/n ");
}
Int m_data;
};
Template <typename _ type> class threadparamt
{
Volatile ulong m_cref;
// The Private destructor ensures that the lifetime of objects is automatically managed by reference count
~ Threadparamt ()
{
Printf ("~ Threadparamt (): m_cref = % d/N ", m_cref );
}
Public:
Ulong addref ()
{
Return (ulong) interlockedincrement (volatile long *) & m_cref );
}
Ulong release ()
{
If (interlockeddecrement (volatile long *) & m_cref) = 0)
{
Delete this;
Return 0;
}
Return m_cref;
}
Threadparamt ():
M_cref (1)
{
Printf ("threadparamt (): m_cref = % d/N", m_cref );
}
_ Type T;
};
// Thread process: a thread process that is executed for a long time
// Addref () and release () must be called in pairs in the thread
Static DWORD winapi longtimethreadproc (lpvoid lpparam)
{
Threadparamt <cuserdata> * pthrparam = (threadparamt <cuserdata> *) lpparam;
// Add reference count immediately at the entrance
Pthrparam-> addref ();
// Simulate a long task
Printf ("longtimethreadproc: do a long time job.../N ");
Sleepex (10000, 0 );
// The reference count must be reduced when the returned result is returned.
Pthrparam-> release ();
Return 0;
}
Int main ()
{
// Create a thread process parameter. After this parameter is passed to the thread, the lifetime is controlled by the reference count.
Threadparamt <cuserdata> * thrparam = new threadparamt <cuserdata> ();
DWORD dwthrid;
Handle hthread = crtcreatethread (0, 0, longtimethreadproc, (lpvoid) thrparam, 0, & dwthrid );
// The following Code assumes that we are not waiting for the end of thread execution
// At this time, it is appropriate to manage the reference count for the lifetime of thrparam.
DWORD dwret = waitforsingleobject (hthread, 5000 );
Assert (dwret = wait_timeout );
Closehandle (hthread );
// The thread data can still be accessed at this time. Check whether critical zone protection is used.
Printf ("still accessible thread data: % d/N", thrparam-> T. m_data );
// Release reference count at this time. If the thread is not finished, the data is not released.
Thrparam-> release ();
Sleepex (6000, 0 );
Printf ("thrparam is unavailable, and thread data cannot be accessed at this time: % d/N", thrparam-> T. m_data );
Return 0;
}