Skip to content

Instantly share code, notes, and snippets.

@aprell
Created June 14, 2013 15:15
Show Gist options
  • Select an option

  • Save aprell/5782659 to your computer and use it in GitHub Desktop.

Select an option

Save aprell/5782659 to your computer and use it in GitHub Desktop.
Sending a cancellation request with pthread_cancel
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
static pthread_t threads[2];
static int IDs[2] = { 1, 2 };
static int running;
static int waste_cycles(int n)
{
if (n < 2)
return n;
else
return waste_cycles(n-1) + waste_cycles(n-2);
}
static void cleanup_handler(void *args)
{
int ID = *(int *)args;
printf("Thread %d is in cleanup handler\n", ID);
}
static void *thread_func_2(void *unused)
{
int state, type;
running = 1;
// Threads can be canceled at cancellation points (default)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &state);
assert(state == PTHREAD_CANCEL_ENABLE);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &type);
assert(type == PTHREAD_CANCEL_DEFERRED);
// pthread_cleanup_push and pthread_cleanup_pop may be implemented as
// macros that expand to text containing '{' and '}', respectively.
// => cleanup handler is lexically scoped
pthread_cleanup_push(cleanup_handler, &IDs[1]);
while (1) {
pthread_testcancel(); // cancellation point
waste_cycles(30);
}
pthread_cleanup_pop(0);
printf("This is never reached\n");
return NULL;
}
static void *thread_func_1(void *unused)
{
// Make sure the other thread is up and running
while (!*(volatile int *)&running) ;
pthread_cancel(threads[1]);
printf("Thread %d exits\n", IDs[0]);
return NULL;
}
int main(void)
{
void *ret;
pthread_create(&threads[0], NULL, thread_func_1, &IDs[0]);
pthread_create(&threads[1], NULL, thread_func_2, &IDs[1]);
pthread_join(threads[0], &ret);
assert(ret == NULL);
pthread_join(threads[1], &ret);
assert(ret == PTHREAD_CANCELED);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment