Saturday, November 1, 2014

Unix Prog: Thread Cancel Option

1. cancelability state and cancelability type

cancelability state decide whether the thread should cancel itself in case it receives one cancel request.

cancelability type decide the way the thread respond to cancel request.

System Definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/pthread.h  
 ......  
 /* Functions for handling cancellation.  
   
   Note that these functions are explicitly not marked to not throw an  
   exception in C++ code. If cancellation is implemented by unwinding  
   this is necessary to have the compiler generate the unwind information. */  
   
 /* Set cancelability state of current thread to STATE, returning old  
   state in *OLDSTATE if OLDSTATE is not NULL. */  
 extern int pthread_setcancelstate (int __state, int *__oldstate);  
   
 /* Set cancellation state of current thread to TYPE, returning the old  
   type in *OLDTYPE if OLDTYPE is not NULL. */  
 extern int pthread_setcanceltype (int __type, int *__oldtype);  
   
 /* Cancel THREAD immediately or at the next possibility. */  
 extern int pthread_cancel (pthread_t __th);  
   
 /* Test for pending cancellation for the current thread and terminate  
   the thread as per pthread_exit(PTHREAD_CANCELED) if it has been  
   cancelled. */  
 extern void pthread_testcancel (void);  
 ......  
 /* Cancellation */
 enum
 {
   PTHREAD_CANCEL_ENABLE,
 #define PTHREAD_CANCEL_ENABLE   PTHREAD_CANCEL_ENABLE
   PTHREAD_CANCEL_DISABLE
 #define PTHREAD_CANCEL_DISABLE  PTHREAD_CANCEL_DISABLE
 };
 enum
 {
   PTHREAD_CANCEL_DEFERRED,
 #define PTHREAD_CANCEL_DEFERRED PTHREAD_CANCEL_DEFERRED
   PTHREAD_CANCEL_ASYNCHRONOUS
 #define PTHREAD_CANCEL_ASYNCHRONOUS     PTHREAD_CANCEL_ASYNCHRONOUS
 };
......

1) Default thread's cancelability state is: PTHREAD_CANCEL_ENABLE, meaning that the thread will be cancelled when receiving a cancel request. If the state is changed to PTHREAD_CANCEL_DISABLE, the cancel requests will be pending. When state is changed back to PTHREAD_CANCEL_ENABLE again, the thread will act on any cancel request at next cancellation point.

2) Cancellation point is the place where the thread checks to see if the function has any pending cancel request. Many POSIX.1 functions are cancellation points.
pthread_testcancel is self-defined cancellation point.

3) Thread will only check cancellation point if the thread is setup to be deferred cancellation. The thread by default has the deferred cancellation type, we can change it using pthread_setcanceltype, to be PTHREAD_CANCEL_ASYNCHRONOUS, which will cause the thread to cancel immediately after receiving the cancel request.

2. Example:
thread.c
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<pthread.h>  
   
 void* func(void* arg)  
 {  
  printf("sub thread run!\n");  
  printf("Change the thread cancellability type to disabled\n");  
   
  int old_state;  
  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);  
  sleep(2);  
   
  printf("sub thread is not cancelled and exit normally!\n");  
 }  
   
 int main(int argc, char* argv[])  
 {  
  pthread_t tid;  
  if(pthread_create(&tid, NULL, func, NULL) != 0) {  
   printf("pthread_create error!\n");  
   exit(1);  
  }  
   
  sleep(1);  
  pthread_cancel(tid);  
  sleep(2);  
  exit(0);  
 }  

shell:
The program firstly launch the sub thread, and fall into sleeping, during this 1 second, the sub thread change the cancel state to "DISABLED", and falling into sleep to wait for the cancel request from main thread.
After one second, main thread wake up, send the cancel request, but the sub thread totally ignore that, then main thread fall into sleep to wait for sub thread finish firstly, the sub thread wake up and finish, lastly the main thread finish.
 ubuntu@ip-172-31-23-227:~$ ./thread.out  
 sub thread run!  
 Change the thread cancellability type to disabled  
 sub thread is not cancelled and exit normally!  

No comments:

Post a Comment