6

I am building a program that, for testing purposes can create N number of threads in C++. I am relativity new to C++ and my current attempt so far is

//Create a list of threads
std::vector<std::thread> t;
for(i=0; i < THREADS; i ++){
    std::thread th = std::thread([](){ workThreadProcess(); });
    t.push_back(th);
    printf("Thread started \n");
    }

for(std::thread th : t){
    th.join();
}

I currently an error that says call to deleted constructor of 'std::thread'. I am unusre what this means or how to fix in

Note:
I have looked at:

But I don't feel they answer my question. Most of them use pthreads or a a different constructor.

shizhen
  • 12,251
  • 9
  • 52
  • 88
C. Begley
  • 121
  • 1
  • 9
  • When asking about build errors, first of all try to create a [Minimal, **Complete**, and Verifiable Example](http://stackoverflow.com/help/mcve) that you can show us. Then copy-paste (as text) the full and complete build log from that example into the question body. And please mark out the lines in the example where the errors are, with for example comments. Also please take some time to review [how to ask good questions](http://stackoverflow.com/help/how-to-ask), as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Nov 15 '18 at 23:04
  • 3
    A hint though: You loop joining the threads should probably not *copy* the thread objects. – Some programmer dude Nov 15 '18 at 23:05
  • 2
    The error message isn't lieing. std::thread is defined with 'thread(const thread&) = delete;' You cannot copy it. How would you write the copy constructor for a thread, if it was you? Can you identify the copy in your code and fix that somehow? – Christopher Pisz Nov 15 '18 at 23:22
  • 3
    Hint: Threads are not copyable. – NathanOliver Nov 15 '18 at 23:23

1 Answers1

11

You can't copy threads. You need to move them in order to get them into the vector. Also, you can't create temporary copies in the loop to join them: you have to use a references instead.

Here a working version

std::vector<std::thread> t;
for(int i=0; i < THREADS; i ++){
    std::thread th = std::thread([](){ workThreadProcess(); });
    t.push_back(std::move(th));  //<=== move (after, th doesn't hold it anymore 
    std::cout<<"Thread started"<<std::endl;
    }

for(auto& th : t){              //<=== range-based for uses & reference
    th.join();
}

Online demo

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • 4
    This is the right explanation of the error, but OP would probably be better off using `emplace_back` as in `t.emplace_back([] { workThreadProcess(); });` rather than creating a `std::thread` object only to move it – Ryan Haining Nov 15 '18 at 23:58
  • How would you pass an argument to the function `workThreadProcess`? – tomtom1-4 Mar 18 '22 at 10:47
  • 1
    @tomtom1-4 just pass the argument. Since it's in a lambda, you need to ensure capture. Example, here: https://ideone.com/78DbTf – Christophe Mar 18 '22 at 11:10
  • Mhh, your example runs fine but it doesn't work inside my program. Are there complications if you pass multiple arguments or arguments by reference? – tomtom1-4 Mar 18 '22 at 12:56
  • @tomtom1-4 yes, this works fine for value arguments, but not for reference. There are two obstacles here: the first, is that I didn't make a capture by reference (more [here](https://en.cppreference.com/w/cpp/language/lambda)). The second is that `thread` uses a reference to a copy if you do not use `std::ref()` as explained [here](https://stackoverflow.com/a/34078246/3723423) – Christophe Mar 18 '22 at 17:24