Why this cause undefined behavior?
#include <iostream>
#include <thread>
#include <vector>
std::vector<std::thread> threads(3);
void task() { std::cout<<"Alive\n";}
void spawn() {
for(int i=0; i<threads.size(); ++i)
//threads[i] = std::thread(task);
threads.emplace_back(std::thread(task));
for(int i=0; i<threads.size(); ++i)
threads[i].join();
}
int main() {
spawn();
}
If I will create threads as in commented line thread is copied/moved assignment so its fine, but why is not working when creating thread in place?
What is happening in your code is that you construct three default threads, then add three further threads.
Change:
std::vector<std::thread> threads(3);
To:
std::vector<std::thread> threads;
const size_t number_of_threads = 3;
int main() {
threads.reserve(number_of_threads);
spawn();
}
And inside spawn:
void spawn() {
for (int i = 0; i < number_of_threads; ++i) {
threads.emplace_back(std::thread(task));
}
for (int i = 0; i < threads.size(); ++i) {
threads[i].join();
}
}
When you are using emplace_back or push_back, you must not allocate the memory before, because that will call the constructor of threads. You should just reserve it.
BTW, since you are using emplace_back not push_back you can directly write:
threads.emplace_back(task);
Related
I have a program where many threads do some computations and write a boolean true value in a shared array to tag the corresponding item as "dirty". This is a data race, reported by ThreadSanitizer. Nevertheless, the flag is never read from these threads, and since the same value is written by all threads, I wonder if it is an actually problematic data race.
Here is a minimal working example:
#include <array>
#include <cstdio>
#include <thread>
#include <vector>
int
main()
{
constexpr int N = 64;
std::array<bool, N> dirty{};
std::vector<std::thread> threads;
threads.reserve(3 * N);
for (int j = 0; j != 3; ++j)
for (int i = 0; i != N; ++i)
threads.emplace_back([&dirty, i]() -> void {
if (i % 2 == 0)
dirty[i] = true; // data race here.
});
for (std::thread& t : threads)
if (t.joinable())
t.join();
for (int i = 0; i != N; ++i)
if (dirty[i])
printf("%d\n", i);
return 0;
}
Compiled with g++ -fsanitize=thread, a data race is reported on the marked line. Under which conditions can this be an actual problem, i.e. the dirty flag for an item i would not be the expected value?
i'm new in c++ programing and need some help to use a thread library with vector library...
first I follow this tutorial
but the compiler (visual studio 2013) show me errors and I don't know how correct it:
first declaration of function
void Fractal::calcIterThread(vector<vector<iterc>> &matriz, int desdePos, int hastaPos, int idThread){
...
}
in main loop
vector<vector<iterc>> res;
res.resize(altoPantalla);
for (int i = 0; i < altoPantalla; i++){
res[i].resize(anchoPantalla);
}
int numThreads = 10;
vector<thread> workers(numThreads);
for (int i = 0; i < numThreads; i++){ //here diferent try
thread workers[i] (calcIterThread, ref(res), inicio, fin, i)); // error: expresion must have a constant value
workers[i] = thread(calcIterThread, ref(res), inicio, fin, i)); // error: no instance of constructor "std::thread::thread" matches the argument list
}
...rest of code...
thanks for any help to clarify
Try this:
#include <functional>
#include <thread>
#include <vector>
// ...
int numThreads = 10;
std::vector<std::thread> workers;
for (int i = 0; i != numThreads; ++i)
{
workers.emplace_back(calcIterThread, std::ref(res), inicia, fin, i);
}
for (auto & t : workers)
{
t.join();
}
finally I can solve the problem with this change in my code...
workers.emplace_back(thread{ [&]() {
calcIterThread(ref(res), inicio, fin, i);
}});
I have a integer variable, that contains the number of threads to execute. Lets call it myThreadVar. I want to execute myThreadVar threads, and cannot think of any way to do it, without a ton of if statements. Is there any way I can create myThreadVar threads, no matter what myThreadVar is?
I was thinking:
for (int i = 0; i < myThreadVar; ++i) { std::thread t_i(myFunc); }, but that obviously won't work.
Thanks in advance!
Make an array or vector of threads, put the threads in, and then if you want to wait for them to finish have a second loop go over your collection and join them all:
std::vector<std::thread> myThreads;
myThreads.reserve(myThreadVar);
for (int i = 0; i < myThreadVar; ++i)
{
myThreads.push_back(std::thread(myFunc));
}
While other answers use vector::push_back(), I prefer vector::emplace_back(). Possibly more efficient. Also use vector::reserve(). See it live here.
#include <thread>
#include <vector>
void func() {}
int main() {
int num = 3;
std::vector<std::thread> vec;
vec.reserve(num);
for (auto i = 0; i < num; ++i) {
vec.emplace_back(func);
}
for (auto& t : vec) t.join();
}
So, obvious the best solution is not to wait previous thread to done. You need to run all of them in parallel.
In this case you can use vector class to store all of instances and after that make join to all of them.
Take a look at my example.
#include <thread>
#include <vector>
void myFunc() {
/* Some code */
}
int main()
{
int myThreadVar = 50;
std::vector <thread> threadsToJoin;
threadsToJoin.resize(myThreadVar);
for (int i = 0; i < myThreadVar; ++i) {
threadsToJoin[i] = std::thread(myFunc);
}
for (int i = 0; i < threadsToJoin.size(); i++) {
threadsToJoin[i].join();
}
}
#include <iostream>
#include <thread>
void myFunc(int n) {
std::cout << "myFunc " << n << std::endl;
}
int main(int argc, char *argv[]) {
int myThreadVar = 5;
for (int i = 0; i < myThreadVar; ++i) {
std::cout << "Launching " << i << std::endl;
std::thread t_i(myFunc,i);
t_i.detach();
}
}
g++ -std=c++11 -o 35106568 35106568.cpp
./35106568
Launching 0
myFunc 0
Launching 1
myFunc 1
Launching 2
myFunc 2
Launching 3
myFunc 3
Launching 4
myFunc 4
You need to store the thread so you can send it to join.
std::thread t[myThreadVar];
for (int i = 0; i < myThreadVar; ++i) { t[i] = std::thread(myFunc); }//Start all threads
for (int i = 0; i < myThreadVar; ++i) {t[i].join;}//Wait for all threads to finish
I think this is valid syntax, but I'm more used to c so I am unsure if I initialized the array correctly.
i'm new in c++ programing and need some help to use a thread library with vector library...
first I follow this tutorial
but the compiler (visual studio 2013) show me errors and I don't know how correct it:
first declaration of function
void Fractal::calcIterThread(vector<vector<iterc>> &matriz, int desdePos, int hastaPos, int idThread){
...
}
in main loop
vector<vector<iterc>> res;
res.resize(altoPantalla);
for (int i = 0; i < altoPantalla; i++){
res[i].resize(anchoPantalla);
}
int numThreads = 10;
vector<thread> workers(numThreads);
for (int i = 0; i < numThreads; i++){ //here diferent try
thread workers[i] (calcIterThread, ref(res), inicio, fin, i)); // error: expresion must have a constant value
workers[i] = thread(calcIterThread, ref(res), inicio, fin, i)); // error: no instance of constructor "std::thread::thread" matches the argument list
}
...rest of code...
thanks for any help to clarify
Try this:
#include <functional>
#include <thread>
#include <vector>
// ...
int numThreads = 10;
std::vector<std::thread> workers;
for (int i = 0; i != numThreads; ++i)
{
workers.emplace_back(calcIterThread, std::ref(res), inicia, fin, i);
}
for (auto & t : workers)
{
t.join();
}
finally I can solve the problem with this change in my code...
workers.emplace_back(thread{ [&]() {
calcIterThread(ref(res), inicio, fin, i);
}});
Say I have something like this:
#include <iostream>
#include <Poco/Mutex.h>
Poco::FastMutex mutex;
int main()
{
for(int i = 0; i < 10; ++i)
{
Poco::FastMutex::ScopedLock lock(mutex);
// do some stuff...
}
return 0;
};
Will the mutex be acquired on every iteration or only once? If I want to protect the whole loop, would it be better to move it outside, like this?
{
Poco::FastMutex::ScopedLock lock(mutex);
for(int i = 0; i < 10; ++i)
{
// do some stuff...
}
return 0;
}
The mutex will be acquired at each iteration.
So yes, you have to move the lock outside the loop to protect the whole loop.