0

I am using the following code:

#include <unistd.h>
#include <pthread.h>
#include <stdio.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void
clean(void *arg)
{
    printf("thread clean: %ld\n", (unsigned long)arg);
}

void*
thread_template(void *arg)
{
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
    pthread_cleanup_push(clean, (void*)pthread_self());
    printf("thread: %ld\n", (unsigned long)pthread_self());
    while ( 1 ) {}
    pthread_cleanup_pop(0);
    pthread_exit((void*)0);
}

int
main(int argc, char const *argv[]) {

    pthread_t tid;
    pthread_create(&tid, NULL, thread_template, NULL);

// waiting for 2 seconds
    sleep(2);

    pthread_cancel(tid);
    pthread_join(tid, NULL);
}

It works fine both on FreeBSD 11 and Ubuntu 16, outputs are like this:

thread: 1994462320
thread clean: 1994462320

But on macOS, it seems pthread_cancel() doesn't affect the thread, main thread blocks at pthread_join(), the clean function never execute(only the first row was output).

So, what happened to macOS's pthread? or any wrong with my code ?

ryuu
  • 57
  • 1
  • 10
  • 1
    There seems to be some long standing issues with pthread_cancel on Darwin, there's talk that it will work if the cancellation request is pending when the thread makes the right system call. However in general cancelling a thread is not recommended. It's not very portable (as you've found. For example, Linux hijacks a signal to implement it), and it's not a good way to architect a program. It's far better to use something else (condition variables, semaphores, even ZeroMQ [my favourite]) to send something to the thread to cause its execution path to lead to a clean thread termination. – bazza Mar 30 '17 at 05:56
  • @bazza I can't figure out how to stop a thread arbitrarily(any point of thread) without pthread_cancel(). – ryuu Mar 30 '17 at 06:03
  • 1
    @Kevin Avoid designing situations where that's necessary. Stopping a thread in the middle of something is dangerous -- it might be in the middle of an operation on a shared resource, so interrupting it will deadlock other threads. –  Mar 30 '17 at 06:45
  • @duskwuff I'll follow your advice.;) – ryuu Mar 30 '17 at 06:51

0 Answers0