I've got a class Tester
containing an std:thread
object, and an std::vector
of Tester
. I understand that I can't copy threads, so the push_back
is out of the question, but why emplace_back
is not working? Where is the copy in my code?
#include <iostream>
#include <thread>
#include <vector>
#include <functional>
#include <unistd.h>
class Tester
{
public:
Tester(std::function<void(void)> func) :
th(func)
{
}
~Tester()
{
th.join()
}
private:
std::thread th;
};
std::vector<Tester> testers;
void InnerHelloWorld()
{
std::cout << "Hello from the inner word!\n";
}
int main() {
std::cout << "Hello World!\n";
for(size_t i = 0 ; i < 4 ; i++)
{
testers.emplace_back(InnerHelloWorld);
}
sleep(1);
return 0;
}
const and Thread Safety Therefore all classes available from the standard, e.g. std::vector<>, can safely be accessed from multiple threads in the same manner.
std::thread::operator= thread objects cannot be copied (2).
Changing contents of vector of threadvecOfThreads[1] = std::move(th4); //Destructor of already existing thread object will call terminate vecOfThreads[1] = std::move(th4); //Destructor of already existing thread object will call terminate vecOfThreads[1] = std::move(th4);
A simple solution to check if all elements of a vector are equal is using the std::adjacent_find function. It returns the first occurrence of adjacent elements that satisfies a binary predicate, or end of the range if no such pair is found.
Theres a couple of minor issues in your code
You missed the trailing semi-colon off of:
th.join()
But importantly, you need to give your class a move constructor - the default one is fine:
Tester(Tester&&) = default;
This is needed as when vectors resize themselves they need to move or copy their elements. A move constructor will generally be created for you but in your case having a custom destructor supresses it. See here.
This will let your code compile, but then it'll throw an exception at runtime. This is because you sometimes destruct from moved-from Testers
which will call join on a moved from thread. Fortunately this is an easy fix:
~Tester()
{
if(th.joinable())
th.join();
}
Full working code:
#include <iostream>
#include <thread>
#include <vector>
#include <functional>
#include <unistd.h>
class Tester
{
public:
Tester(std::function<void(void)> func) :
th(func)
{
}
~Tester()
{
if(th.joinable())
th.join();
}
Tester(Tester&&) = default;
private:
std::thread th;
};
std::vector<Tester> testers;
void InnerHelloWorld()
{
std::cout << "Hello from the inner word!\n";
}
int main() {
std::cout << "Hello World!\n";
for(size_t i = 0 ; i < 4 ; i++)
{
testers.emplace_back(InnerHelloWorld);
}
sleep(1);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With