hw03 – `pthread_cancel` either doesn't work, or causes the process to abort
esw.pages.fel.cvut.cz#17 (closed)
In the provided template for RCU, the reader and writer threads are stopped by calling pthread_cancel
. By default, pthread threads use the deferred cancellation type, where the thread is only cancelled in one of the functions listed in man pthreads
, chapter "Cancellation points". However, the readers don't encounter any cancellation points in the main loop when using rwlocks, so the pthread_cancel
call does not actually stop the threads. This can be verified by adding a long sleep after the 2 loops where pthread_cancel
is called and checking in htop
. This occasionally results in race conditions where a reader thread accesses the already-freed list before the whole process terminates.
A reasonable-looking, but wrong fix is to call pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr);
in each spawned thread, which changes the cancellation type to immediately stop the thread. However, C++11 does not like this, and the threads will randomly cause the process to std::terminate()
(see e.g. https://stackoverflow.com/questions/59082973/terminate-called-without-an-active-exception-after-pthread-cancel).
Two possible solutions I see:
- Quick&dirty: Don't cancel the threads, don't free the list and just stop the process, killing all threads and freeing all memory.
- Add a global stop flag, which is checked in the
while
loops of the spawned threads, set it frommain
and then usepthread_join
to wait for the threads before cleaning up. However, this might have a minor performance impact, although I doubt that it's relevant.