0

I have something like a list of things to calculate, and they are somewhat dependent on eachother (some of those calculations, may show that other calculations on the list are not needed).

Also I want to calculate always two of them at a time (two child threads and one main thread (which is a child thread of another one, but that's another story)).

So I want the main thread to wait for ANY of the two treads -the one that finishes first makes the main thread continue-. After it continues, it will run some code to see if the other running thread can be killed (if the one that finished shows that the other is not needed), or not, and also to run a new thread.

The idea is to do something like this:

while (/*list not empty*/) {
    /*detect which two entries need to be calculated*/
    /*detect if running thread can be killed*/

    if (/*running thread can be killed*/) {
        pthread_join(/*threadnum*/, NULL)
    }

    switch (/*how many threads already running?*/) {
    case 0:
        pthread_create(/*&threadnum*/, NULL, /*calculate*/, /*foo*/);
    case 1:
        pthread_create(/*&threadnum*/, NULL, /*calculate*/, /*foo*/);
        break;
    }

    /* !!!!!!!!! Question code is next line: !!!!!!!!!*/
    pthread_join(/*What goes here?*/, NULL);
    // If it is impossible to do with pthread_join, what else can be used?
}

My first approach (if this was impossible) would be to store in an array the status of both threads, and check every second (with a while and sleep(1)) if any of them finished, but that would make me lose time (between 0 and 1 seconds) every time a thread finishes. So I want to avoid that if possible.

EDIT: pthread_cond_wait(/* something */) seems the way to go. However I want it to be easy: the main thread and both child threads share a global variable (parent) that is set to 0 if child threads are running, and is set to 1 when one of them stops. Ideally I want to control from the main thread everything in this way:

while (/*list not empty*/) {
    /*detect which two entries need to be calculated*/
    /*detect if running thread can be killed*/

    if (/*running thread can be killed*/) {
        pthread_join(/*threadnum*/, NULL)
    }

    switch (/*how many threads already running?*/) {
    case 0:
        pthread_create(/*&threadnum*/, NULL, /*calculate*/, /*foo*/);
    case 1:
        pthread_create(/*&threadnum*/, NULL, /*calculate*/, /*foo*/);
        break;
    }

    /* !!!!!!!!! Question code is next line: !!!!!!!!!*/
    pthread_cond_wait(parent, /*wtf?*/)
}

Now I have an idea to stop the parent until that condition is met, which I can set to 1 inside the child threads.

  • 1
    Do you understand how to use condition variables? If not, I'd start by learning how to use them fairly thoroughly. Also, here's an extremely valuable tip -- stop thinking about waiting for threads or stopping threads. Threads are just the things that happen to be doing the work, but it's the *work* that you want to wait for or stop. You want to wait until some work is done. You want to stop some work from being done. Don't think about what happens to do the work, think about the work itself. – David Schwartz Sep 15 '17 at 22:56
  • @DavidSchwartz yes, I know condition variables. The problem is: the only ways I know to wait for something in C are two: 1.- pthread_join(): As far as I know you can only use it to wait for one thread, not two, so it is not useful. 2.- check every x time if work is done (while and Sleep()), which makes you lose the time between the moment the thread finished, and the moment you realize that at the main thread. – alx - recommends codidact Sep 15 '17 at 23:10
  • All comments but the one that I specifically ask what goes there, are not because I don't know what to put there, but to be generic. – alx - recommends codidact Sep 15 '17 at 23:11
  • 2
    "I know condition variables. The problem is: the only ways I know to wait for something in C are two..." - condition variables are a third way... – Crowman Sep 15 '17 at 23:41
  • Okayyy, I thought he was talking about variables for the ifs. I didn't know that there exists something called "CONDITION VARIABLES" that is specifically for pthreading, so apologies. – alx - recommends codidact Sep 15 '17 at 23:50
  • How long does one thread take to complete normally? – John Zwinck Sep 16 '17 at 00:12
  • From miliseconds to hours. – alx - recommends codidact Sep 16 '17 at 00:29
  • @CacahueteFrito Once you learn how to use condition variables thoroughly, you will understand how to properly wait for complex conditions to occur. – David Schwartz Sep 17 '17 at 19:07
  • @CacahueteFrito It sounds like your question is now "what is a condition variable and how do you use one?". That's a very generic question that any search engine can help you with. You can start with [this introduction](https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.genprogc/condition_variables.htm). – David Schwartz Sep 18 '17 at 16:45
  • Yes, it is; and yes, it seems an easy question, so this is solved. Thanks! – alx - recommends codidact Sep 18 '17 at 22:43

1 Answers1

0

Instead of making the main thread monitor and try to kill other threads, make the other threads communicate directly amongst themselves.

For example, if thread A finishes and it becomes clear that the computation in thread B is no longer needed, simply set a boolean flag. Make thread B check that flag between steps of its computation, and give up if the flag is set.

Trying to interrupt threads is bad practice--you're better off just setting a flag that the threads will check.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436