Reputation: 4537
Let a multithreaded (pthreads) C program have a tree of (joinable/attached) threads like this:
main
└── th0
├── th1
│ ├── th3
│ └── th4
│ ├── th5
│ └── th6
└── th2
├── th7
│ └── th9
└── th8
Any thread 'thX
' can have up to 2 child threads.
The tree is dynamic: branches are cut, and new threads are created continuously.
When a condition is met, I would like to kill not a thread, but a branch of threads. That is, if I want to kill th2
, I also want all these to be killed: th7
, th8
& th9
.
What would be the best(most efficient/most readable) way to do this?
What would be the best(most efficient/most readable) way to keep track of the tree?
Now I'm using a _Thread_local
variable to keep the name (X
) of a thread, another one to keep the name of its parent, and an array of lenght 2 to keep the names of the childs, but that only allows me to kill a child, not grand-childs and so on.
I don't know if it is relevant, but I'm using GNU/Linux and GCC6
PS: I do want to force kill the threads. I don't malloc, so leaking isn't a problem.
PS.2: It's part of a Branch & Bound algorithm; and this is the bound part.
Upvotes: 0
Views: 125
Reputation: 26
See if this works for you. Each "parent" thread can push cleanup routines which will cancel their children. When you want to cancel the subtree, you do a pthread_cancel() on the parent....
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void cancel_child(void *ptr)
{
printf("cancelling child\n");
pthread_cancel(*((pthread_t *) ptr));
}
void *runner(void *ptr)
{
pthread_t thr1, thr2;
long depth;
depth = (long) ptr;
if (!(--depth)) return NULL;
pthread_create(&thr1, NULL, runner, (void *) depth);
pthread_cleanup_push(cancel_child, (void *) &thr1);
pthread_create(&thr2, NULL, runner, (void *) depth);
pthread_cleanup_push(cancel_child, (void *) &thr2);
if (depth == 2) {
sleep(1);
// cancel the subtree
pthread_cancel(thr1);
pthread_cancel(thr2);
}
sleep(10 - depth);
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
}
int main()
{
runner((void *) 3);
}
Upvotes: 1