1

I have a function that I want to run in different threads. The function populates a data structure, for example:

per_thread(int start_value, std::vector<SomeStruct>& reference)
{
    for ( size_t i = 0; i < 500; i++ )
    {
        reference.push_back(func(i));
        if (i == 2)
            send_signal_back();
    }
}

However, after this is done going through the loop some number of times, I want to start another thread, using this as the start value. Unfortunately, I don't understand how to send a signal back to the parent thread.

So I want something like this:

for( size_t j = 0; j < 5000; j += num_threads)
{
    for (size_t i = 0; i < num_threads; i++)
    {
        std::async(per_thread(foo(j+i), std::ref(vec));
        //wait for signal
    }
}

How do I send such a signal?

Andrew Spott
  • 3,457
  • 8
  • 33
  • 59
  • There is no "parent-child" relationship between threads. Threads are just threads. Maybe you were thinking of processes? – Kerrek SB May 03 '13 at 21:29
  • 1
    @KerrekSB: There isn't an enforced parent-child relationship, but some thread creates some other thread (other than the master thread), so in that sense, there is a parent-child relationship. I'm not thinking of processes, at least not as far as I understand it. I'm still new to concurrency in general. – Andrew Spott May 03 '13 at 21:31
  • How about some [condition variable](http://en.cppreference.com/w/cpp/thread/condition_variable)? – Some programmer dude May 03 '13 at 21:32
  • How about a (*thread safe*) message queue and having the main thread periodically check it? – Ryan May 03 '13 at 21:33
  • 1
    Concurrency *is* really hard... anyway, no, there really isn't such a relationship, not as far as C++ is concerned. All the threads are really just threads. They all do the same thing. It's true that only one thread enters `main`, but that's not material. – Kerrek SB May 03 '13 at 21:33
  • @JoachimPileborg: `func` represents some sequence of logic that is fairly self-contained, and `start_value` represents some dependency that the `per_thread` has. – Andrew Spott May 03 '13 at 21:35
  • Ohh, by the way, you *really* better fix accessing that shared vector! – Kerrek SB May 03 '13 at 21:43
  • @KerrekSB: I'm aware of that... but that is for another question, if I can't figure it out :) – Andrew Spott May 03 '13 at 21:54
  • @AndrewSpott the problem is that your low level pseudo-code does not make sense, and you aren't giving a high-level description of your actual problem. Some questions: "using this as the start value" -- what do you mean by "this"? "some number of times" -- what number of times, determined by what? "I want to start another thread" -- threads are solutions to problems, not the problems themselves. Describe the actual problem. "so I want something like this" -- you mean, something that executes undefined behavior? Something that uses threads but serializes everything they do? – Yakk - Adam Nevraumont May 04 '13 at 00:47

1 Answers1

4

I wouldn't use async, because that's too high-level and does something else. (Here's a little rant of mine that touches on async.)

It looks like you really just want threads and control them manually.

Try this:

#include <vector>
#include <thread>

std::vector<std::thread> threads;

for (std::size_t j = 0; j < 5000; j += num_threads)
{
    for (std::size_t i = 0; i != num_threads; ++i)
    {
         threads.emplace_back(per_thread, foo(i + j), std::ref(vec));
    }
}

for (auto & t: threads)
{
    t.join();
}

This will finish once the longest-running thread has finished. (The "long-tail" effect.)

Community
  • 1
  • 1
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • So, when doing that, the threads are fairly independent: the second thread doesn't depend on the intermediate result of the first thread. I think my question might not be super clear, I'm going to attempt to fix it. – Andrew Spott May 03 '13 at 21:37
  • 3
    @AndrewSpott: OK, but let me warn you that if your individual rounds depend on each other, then you should think really really hard about the parallelisation design before you start coding this. Poorly sharing parallel code may be disastrously slower than single-threaded code. You want to avoid *any* kind of sharing as much as possible. – Kerrek SB May 03 '13 at 21:38
  • I think it is a little more clear now. `func` represents some computationally expensive function which only depends on it's inputs, which is why I'm positive that this will speed up my code – Andrew Spott May 03 '13 at 21:41