0
int
main()
{
  std::mutex io;
  std::vector<std::future<void>> futures;
  std::cout << "Main id: " << std::this_thread::get_id() << std::endl;
  for (int i = 0; i < 12; ++i) {
    std::future<void> f = std::async(std::launch::async, [&]{
      std::this_thread::sleep_for(std::chrono::seconds(10));
      io.lock();
      std::cout << "Thread id: " << std::this_thread::get_id() << std::endl;
      io.unlock();
    });
    futures.push_back(std::move(f));
  }
  for (auto& f : futures) {
    f.wait();
  }
}

I have read on several blogs that I can not use async for task based concurrency because it doesn't distribute tasks evenly on the threads, so I created a small test program.

Main id: 140673289357120
Thread id: 140673241089792
Thread id: 140673215911680
Thread id: 140673232697088
Thread id: 140673224304384
Thread id: 140673207518976
Thread id: 140673199126272
Thread id: 140673165555456
Thread id: 140673190733568
Thread id: 140673173948160
Thread id: 140673182340864
Thread id: 140673157162752
Thread id: 140673148770048

But the output is not something that I expected. My machine has 2 cores with hyper-threading which gives me 4 threads, but looking at the thread ids it seems that they are all unique.

Can async be used for task based concurrency?

What exactly does this_thread::get_id() return?

By task based concurrency I mean that the work will be split evenly between all available threads.

Maik Klein
  • 15,548
  • 27
  • 101
  • 197
  • To answer your second question, the `get_id` function return a [`std::thread::id`](http://en.cppreference.com/w/cpp/thread/thread/id) object. Exactly what that is is up to the implementation. – Some programmer dude Dec 22 '15 at 10:35
  • As for your first question, you should check e.g. [this `std::async` reference](http://en.cppreference.com/w/cpp/thread/async), which says "The template function `async` runs the function `f` asynchronously (***potentially*** in a separate thread which ***may*** be part of a thread pool)" (emphasis mine). To answer your question one has to take that into consideration, *and* know what you mean by "task based concurrency". – Some programmer dude Dec 22 '15 at 10:36
  • See this Q&A for similar information http://stackoverflow.com/questions/15666443/which-stdasync-implementations-use-thread-pools – Darien Pardinas Dec 22 '15 at 11:37

1 Answers1

2

The 12 unique thread ids refers to the software threads and not hardware threads. In task manager panel on Windows (7 or 10) I see number of threads in thousands, which are again software threads that are executed concurrently on available hardware threads based on time slicing.

async is suitable for task based concurrency. There are some issues with this as follows:

  1. There is no guarantee that the task will be executed in a separate thread if the launch policy is not specified. Implementation may choose to execute the task in same thread depending on certain conditions (too many threads for example).

  2. If the return value of asynch call (future<>) is not captured, then, the execution of current thread will be blocked immediately. It is same as serial program. This happens even if async policy is specified.

  3. The destructor of future<> returned by async will block the execution (if the execution of async call is not finished).

Rushikesh
  • 163
  • 8