Notes for pthread_cancel function
/**************************************************
The correlation function:
#include <pthread.h>
int pthread_cancel(pthread_t thread)
Successful return 0, failure return error code
**************************************************/
This function is provided by POSIX to cancel other threads in the same process.
Several cancel requests are sent without waiting for the process to be cancelled to exit! Threads can
Choose to ignore or choose other actions!
It should be noted that:
When we call it to cancel an already acquired mutex/anonymous semaphore/write lock...
If the thread that has not released its acquired lock is cancelled, then all of you want to
Threads that want to perform tasks at this time will be asleep until the lock is released.
To avoid this problem, we can call a set of functions:
/**************************************************
#include <pthread.h>
void pthread_cleanup_push(void (*routine)(void *), void *arg)
void pthread_cleanup_pop(int execute)
Parametric interpretation: routine is a function pointer and arg is a parameter passed to routine
When execute is zero, the registered function is deleted from the stack and will be deleted again.
Not executed.
**************************************************/
These two functions are called thread cleanup handlers, similar to atexit functions, and we
Multiple cleanup functions can be registered, and when the following actions are performed, the functions we register will be
Callback (reverse order of execution and registration):
1. When a thread exits from the pthread_exit(void *) function.
2. When the thread responds to the cancellation request.
3. Execute the pthread_cleanup_pop function when the execute parameter is non-zero.
These two thread cleanup handlers must appear in pairs and must be in the same scope.
Otherwise, compilation errors will occur.
Example:
//How to use these functions to deal with the above problems!
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <pthread.h>
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
void *count(void *arg)
{
int i=1;
while(1)
{
sleep(1);
printf("sec: %d\n", i++);
}
}
void handler(void *arg)
{
printf("[%u] is cancelled.\n", (unsigned)pthread_self());
pthread_mutex_t *pm = (pthread_mutex_t *)arg;
pthread_mutex_unlock(pm);
}
void *routine(void *arg)
{
#ifdef CLEANUP
pthread_cleanup_push(handler, (void *)&m);
#endif
pthread_mutex_lock(&m);
printf("[%u] lock the mutex!\n", (unsigned)pthread_self());
sleep(2);
printf("[%u]: job finished!\n", (unsigned)pthread_self());
pthread_mutex_unlock(&m);
printf("[%u] unlock the mutex!\n", (unsigned)pthread_self());
#ifdef CLEANUP
pthread_cleanup_pop(0);
#endif
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
pthread_t t, t1, t2;
pthread_create(&t, NULL, count, NULL);
pthread_create(&t1, NULL, routine, NULL);
pthread_create(&t2, NULL, routine, NULL);
printf("[%u] ==> t1\n", (unsigned)t1);
printf("[%u] ==> t2\n", (unsigned)t2);
printf("[%u] ==> main\n", (unsigned)pthread_self());
sleep(1);
pthread_cancel(t1);
pthread_cancel(t2);
sleep(2);
pthread_mutex_lock(&m);
printf("[%u] locked the mutex!\n",
(unsigned)pthread_self());
pthread_mutex_unlock(&m);
exit(0);
}
Posted by nec9716 on Fri, 07 Jun 2019 14:48:45 -0700