A thread cleanup handler in Linux and Windows thread cancellation:
A cleanup handler is a measure, used to deallocate a resource only if the thread exits or canceled. To register a cleanup handler, need to call pthread_cleanup_push() and
pass a pointer to cleanup function and the void * argument. The pthread_cleanup_pop() function removes the routine at the top of the calling thread's cancellation cleanup
stack and optionally invokes it (if execute is non-zero).
The following sample code shows how a dynamically allocated buffer from a thread can be deallocated on canceling the thread in Linux.
#include < pthread.h >
#include < stdio.h >
#include < string.h >
#include < unistd.h >
char *pgArray = 0;
/* Buffer allocation */
char * allocate_array (size_t size)
{
return new char[size];
}
void release_array (void *pArg)
{
if(pgArray)
{
printf("release_array() called..\n");
delete []pgArray;
}
}
void *Print_Details(void *param)
{
printf("This is secondary thread's entry...\n");
printf("Allocating a buffer of size 20...\n");
pgArray = allocate_array(20);
strcpy(pgArray, "This is a test");
/*Registering the cleanup handler in case thread cancelled/exit*/
pthread_cleanup_push(release_array, NULL);
size_t sIndex = 0;
// An infinite loop to keep the thread busy until thread cancel gets called...
while (pgArray[sIndex] != '\0')
{
printf ("%c\n", pgArray[sIndex]);
sIndex++;
if(pgArray[sIndex] == '\0')
{
sleep(1);
sIndex = 0;
}
}
printf("This is secondary thread's exit...\n");
/*Unregister the cleanup handler by passing a nonzero value,
this actually calls the release_array()*/
pthread_cleanup_pop(1);
return NULL;
}
/* Main program */
int main()
{
pthread_t thread;
int thread_ret;
void *status;
printf("This is main... Creating thread with default param\n");
pthread_create(&thread, NULL, &Print_Details, NULL);
sleep(1);
// Called secondary thread cancellation....
printf("Called secondary thread cancellation...\n");
pthread_cancel(thread);
sleep(2);
printf("Main exited\n");
return 0;
}
In Windows, as per Microsoft we should call TerminateThread only when there is no other go. Then the question comes what's the way in Windows, a thread/threads can be
canceled/stopped as required. Microsoft provided a way to do this by implementing following steps:
a. Create an event object using the CreateEvent function.
b. Create the threads.
c. Each thread monitors the event state by calling the WaitForSingleObject function. Use a wait time-out interval of zero.
d. Each thread terminates its own execution when the event is set to the signaled state (WaitForSingleObject returns WAIT_OBJECT_0).
A cleanup handler is a measure, used to deallocate a resource only if the thread exits or canceled. To register a cleanup handler, need to call pthread_cleanup_push() and
pass a pointer to cleanup function and the void * argument. The pthread_cleanup_pop() function removes the routine at the top of the calling thread's cancellation cleanup
stack and optionally invokes it (if execute is non-zero).
The following sample code shows how a dynamically allocated buffer from a thread can be deallocated on canceling the thread in Linux.
#include < pthread.h >
#include < stdio.h >
#include < string.h >
#include < unistd.h >
char *pgArray = 0;
/* Buffer allocation */
char * allocate_array (size_t size)
{
return new char[size];
}
void release_array (void *pArg)
{
if(pgArray)
{
printf("release_array() called..\n");
delete []pgArray;
}
}
void *Print_Details(void *param)
{
printf("This is secondary thread's entry...\n");
printf("Allocating a buffer of size 20...\n");
pgArray = allocate_array(20);
strcpy(pgArray, "This is a test");
/*Registering the cleanup handler in case thread cancelled/exit*/
pthread_cleanup_push(release_array, NULL);
size_t sIndex = 0;
// An infinite loop to keep the thread busy until thread cancel gets called...
while (pgArray[sIndex] != '\0')
{
printf ("%c\n", pgArray[sIndex]);
sIndex++;
if(pgArray[sIndex] == '\0')
{
sleep(1);
sIndex = 0;
}
}
printf("This is secondary thread's exit...\n");
/*Unregister the cleanup handler by passing a nonzero value,
this actually calls the release_array()*/
pthread_cleanup_pop(1);
return NULL;
}
/* Main program */
int main()
{
pthread_t thread;
int thread_ret;
void *status;
printf("This is main... Creating thread with default param\n");
pthread_create(&thread, NULL, &Print_Details, NULL);
sleep(1);
// Called secondary thread cancellation....
printf("Called secondary thread cancellation...\n");
pthread_cancel(thread);
sleep(2);
printf("Main exited\n");
return 0;
}
In Windows, as per Microsoft we should call TerminateThread only when there is no other go. Then the question comes what's the way in Windows, a thread/threads can be
canceled/stopped as required. Microsoft provided a way to do this by implementing following steps:
a. Create an event object using the CreateEvent function.
b. Create the threads.
c. Each thread monitors the event state by calling the WaitForSingleObject function. Use a wait time-out interval of zero.
d. Each thread terminates its own execution when the event is set to the signaled state (WaitForSingleObject returns WAIT_OBJECT_0).
Comments