I was randomly testing std::thread in my virtual linux machine (GCC 4.4.5-Debian) with this test program:
#include <algorithm>
#include <thread>
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
static int i=0;
void f( vector<int> &test)
{
++i;
cout << "Push back called" << endl;
test.push_back(i);
}
int main()
{
vector<thread> t;
vector<int> test;
for( int i=0; i<1000; ++i )
{
t.push_back( thread( bind(f, test) ) );
}
for( auto it = t.begin(); it != t.end(); ++it )
{
(*it).join();
}
cout << test.size() << endl;
for( auto it = test.begin(); it != test.end(); ++it )
{
cout << *it << endl;
}
return 0;
}
Why does vector test remain empty? Am I doing something stupid with references (probably) or is it something with bind or some threading problem?
Thanks!
UPDATE: with the combined help of Kos and villintehaspan I “fixed” the “problem”:
#include <algorithm>
#include <thread>
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
static int i=0;
void f( vector<int> &test)
{
++i;
test.push_back(i);
}
int main()
{
vector<thread> t;
vector<int> test;
for( int i=0; i<1000; ++i )
{
t.push_back( thread(f, std::ref(test)) );
}
for( auto it = t.begin(); it != t.end(); ++it )
{
(*it).join();
}
cout << test.size() << endl;
for( auto it = test.begin(); it != test.end(); ++it )
{
cout << *it << endl;
}
return 0;
}
Which prints all values in order and seems to work OK. Now only one question remains: is this just lucky (aka undefined behavior (TM) ) or is the static variable causing a silent mutex-like step in the code?
PS: I understand the “killing multithreadedness” problem here, and that’s not my point. I’m just trying to test the robustness of the basic std::thread functionality…
Looks to me like a threading problem.
While I’m not 100% sure, it should be noted that all 1000 threads:
do
++ion the same int value (it’s not an atomic operation- you may encounter problems here, you can use__sync_fetch_and_add(&i,1)instead (note that it’s a gcc extension not standard C++);do
push_backsimultaneously on astd::vector, which is not a thread-safe container AFAIK… Same forcoutI think. I believe you’d need to use a locking mechanism around that (std::mutexperhaps? I’ve only used pthreads so far but I believe it’s what you need).Note that this kind of kills any benefit of using threads here, but that’s a consequence of the fact that you shouldn’t use multiple threads at once on a non-thread-safe object.
—-EDIT—-
I had a google on this threading API (not present on my tdm gcc 4.5 on Windows, unfortunately).
Aparrently instead of:
you can just say
and pass an arbitrary number of arguments in this way.
Source: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=422
This should also solve your problem with making a copy of the vector which I haven’t noticed before(+1 for @villintehaspam here).
Actually, one more thing is needed to make sure the copy isn’t created here:
will make sure that the vector isn’t copied.
Wow, I got confused too. 🙂