I'm having some thread programming learning on my virtual machine. The code that do not perform as expected is following:
#include <iostream>
#include <thread>
using namespace std;
void function01() {
for (int i=0; i<100; i++) {
std::cout << "from t1:" << i << std::endl;
}
}
int main() {
// data race and mutex
std::thread t1( function01 );
for (int i=0; i<100; i++) {
std::cout << "from main:" << i << std::endl;
}
t1.join();
return 0;
}
These code should make a data race on std output. But when I compiled it with
:!g++ -std=c++11 -pthread ./foo.cpp
and running, every time I got a result in which 100 times "t1" followed 100 times "main". What confusing me is that when I did the same thing on my another ubuntu14.04 which was installed in my old lap-top, the code performed as my expected. That means this code encountered with data race.
I don't know much about vmware. Are the threads running on the vmware are managed and won't encountered data race?
------------- second edit -----------------------
Thanks for everybody.
The quantity of core might be the main reason. And I had my expected result after setting quantity of vm core to more than one.
Your new machine is probably much faster than your old one. So it is able to complete execution of function01 before main gets to its own loop.
Or it has only one CPU, so it can execute only one routine at a time. And because your loop requires really small amount of computation, CPU could be done with it in one slice of time given to it by OS.
Make sure that your VM has more than one CPU allocated to it. And try to make each step in your loops 'heavier'.
double accumulator = 0;
for (int i=0; i<100; i++) {
for (int j=1; j<1000*1000; j++)
accumulator += std::rand();
std::cout << "from t1:" << i << std::endl;
}
I think the problem is with the time slice. You can verify it by yourself, by introducing some delay in your code. For example:
#include <iostream>
#include <chrono>
#include <thread>
void function01() {
for (int i=0; i<100; i++) {
std::cout << "from t1:" << i << std::endl;
std::this_thread::sleep_for(std::chrono::duration<double, std::milli>{10});
}
}
int main() {
// data race and mutex
std::thread t1( function01 );
for (int i=0; i<100; i++) {
std::cout << "from main:" << i << std::endl;
std::this_thread::sleep_for(std::chrono::duration<double, std::milli>{10});
}
t1.join();
return 0;
}
Related
I am new to C++ and I am trying to create multiple threads using for loop. Here is the code
#include <iostream>
#include <thread>
class Threader{
public:
int foo(int z){
std::cout << "Calling this function with value :" << z << std::endl;
return 0;
}
};
int main()
{
Threader *m;
std::cout << "Hello world!" << std::endl;
std::thread t1;
for(int i = 0; i < 5; i++){
std::thread t1(&Threader::foo, m, i);
t1.join();
}
return 0;
}
This is the output
As you can see the function I am calling is being invoked using Thread 5 times, but I have to do a t1.join inside the for loop. Without the join the for loop fails in the very first iteration. Like shown here
But if I use the join(), then the threads are being created and executed sequentially cause join() waits for each thread completion. I could easily achieve Actual multithreading in Java by creating Threads in a loop using runnable methods.
How can I create 5 threads which would run absolutely parallel in C++?
I need my app to be able to run some methods under a new process, and ideally be able to get a return value from those methods however I have not yet found how I can do this (my C++ knowledge is pretty basic).
So to explain better, let's say I have methods A, A1 and A2. Method A will start executing and at some point it will:
Run method A1 under a new process
Wait for A1 to complete and possibly get return value
Run method A2 under another new process
Wait for A2 to complete and again get return value
Continue running code under original process
I found that I can use fork() to run code in a subprocess, however this does not suit my needs because it seems to be creating a copy of the parent process and not just running the specific code I want only in the new process. Here is an excerpt of what I tried, I'm not sure if it can be modified to do what I want it to or if I should use something else completely:
int main(){
std::cout << "START" << std::endl;
test1();
test2();
std::cout << "FINISH" << std::endl;
return 0;
}
void test1(){
pid_t pid = fork();
if (pid == 0){
int i = 0;
for (; i < 5; ++i) {
std::cout << "Test 1 " << std::endl;
}
}
}
void test2(){
pid_t pid = fork();
if (pid == 0){
int i = 0;
for (; i < 5; ++i) {
std::cout << "Test 2 " << std::endl;
}
}
}
This however results in test2() being executed twice, and FINISH printed 4 times since the parent process is copied to the subprocess.
I am doing this on Linux at the moment, although I'll need to do the same for Windows eventually.
First of all your parent process should wait for the child processes to exit.
Then your child process should exit once they're done, or else the functions will return on both the child and parent processes.
It sound to me like multi-threading might be the best option for you. This way you share the same memory space and can easily get return values. Look into using OpenMP. I think it is by far the easiest way to multi thread. You can launch tasks for each of the function in a parallel block.
int main(){
std::cout << "START" << std::endl;
int ret1, ret2;
#pragma omp parallel
{
#pragma omp task
ret1 = test1();
#pragma omp task
ret2 = test2();
} //blocks at end of parallel block to wait for tasks to finish
std::cout << "FINISH" << std::endl;
return 0;
}
int test1(){
int i = 0;
for (; i < 5; ++i) {
std::cout << "Test 1 " << std::endl;
}
return 0;
}
int test2(){
int i = 0;
for (; i < 5; ++i) {
std::cout << "Test 2 " << std::endl;
}
return 0;
}
I modified the code in my browser so I can not guarantee it compiles but this is how you can launch functions in parallel and get a return value. I do not think forking is the best way to go about it since you would then need some sort of interprocess communication to get data back. Also OpenMP is probably much more efficient. You could also look into using PThreads which is what I think OpenMP uses on the backed but that is more complicated. Also if you are using C++11 look into using std::async(...) which can spawn threads for functions.
I am getting into threading in C++ and was going some testing and got this error.
Here is my code:
#include <iostream>
#include <thread>
#include <unordered_map>
#include <string>
#include <vector>
using namespace std;
static vector<string> thisVector;
void thread1() {
for (int i = 0; i < 400; i++){
thisVector.push_back(to_string(i));
}
cout << "Finished 1" << endl;
return;
}
void thread2() {
for (int i = 0; i < 400; i++){
thisVector.push_back(to_string(i));
}
cout << "Finished 2" << endl;
return;
}
int main(int argc, const char * argv[]) {
thread first(thread1);
thread second(thread2);
first.join();
second.join();
cout << "done threading" << endl;
cout << thisVector.size() << endl;
return 0;
}
The weird thing is, sometimes I get the correct output, so 800. Sometimes I get a number slightly lower than that for I don't know what reason??? And sometimes I get the following error:
malloc: *** error for object 0x100400028: pointer being freed was not allocated
Any help would be greatly appreciated!
Thanks
A std::vector is not thread safe. You have two execution threads modifying the same std::vector concurrently. Operations on a std::vector should, in this case, be protected by a mutex.
The result of this is undefined behavior. As you've observed, sometimes it might work, sometimes wrong results get produced but the program completes successfully, sometimes the program crashes. This is what "undefined behavior" means.
It is worth reading The C++ Programming Language, it covers subjects of interest like : threads, tasks, but also at higher conceptual level future/promise, packaged_task, async.
In your case, you don't only deal with concurrency. You have to deal with shared data of concurrent threads. The way you programmed it does not guarantee any order of execution. That is why you get those strange results.
The error message you mentioned is likely to be because of concurrent access to the shared vector and it says what is wrong: a pointer is being freed (delete), but was not allocated beforehand. You don't see the pointer, it's an internal member of vector.
Your solution is to use a mutex to make sure that whenever a data is pushed back into the vector it does not get interrupted by the other concurrent thread and finishes appropriately, so that the next push_back starts only when the previous one has finished.
You can use a global variable for mutex. Then you need to deal appropriately with locking/unlocking, i.e. you must say when to acquire a mutex (before push_back) and when to release it (after push_back). Since you use only one mutex this should be fairly simple and should work.
You can try something like this:
#include <iostream>
#include <thread>
#include <unordered_map>
#include <string>
#include <vector>
using namespace std;
static vector<string> thisVector;
//Global MUTEX
mutex mv;
//
void thread1() {
for (int i = 0; i < 400; i++){
//Lock before and unlock after push back
mv.lock();
thisVector.push_back(to_string(i));
mv.unlock();
}
cout << "Finished 1" << endl;
return;
}
void thread2() {
for (int i = 0; i < 400; i++){
mv.lock();
thisVector.push_back(to_string(i));
mv.unlock();
}
cout << "Finished 2" << endl;
return;
}
int main(int argc, const char * argv[]) {
thread first(thread1);
thread second(thread2);
first.join();
second.join();
cout << "done threading" << endl;
cout << thisVector.size() << endl;
return 0;
}
I am trying to make use of boost::thread to perform "n" similar jobs. Of course, "n" in general could be exorbitantly high and so I want to restrict the number of simultaneously running threads to some small number m (say 8). I wrote something like the following, where I open 11 text files, four at a time using four threads.
I have a small class parallel (which upon invoking run() method would open an output file and write a line to it, taking in a int variable. The compilation goes smoothly and the program runs without any warning. The result however is not as expected. The files are created, but they are not always 11 in number. Does anyone know what's the mistake I am making?
Here's parallel.hpp:
#include <fstream>
#include <iostream>
#include <boost/thread.hpp>
class parallel{
public:
int m_start;
parallel()
{ }
// member function
void run(int start=2);
};
The parallel.cpp implementation file is
#include "parallel.hpp"
void parallel::run(int start){
m_start = start;
std::cout << "I am " << m_start << "! Thread # "
<< boost::this_thread::get_id()
<< " work started!" << std::endl;
std::string fname("test-");
std::ostringstream buffer;
buffer << m_start << ".txt";
fname.append(buffer.str());
std::fstream output;
output.open(fname.c_str(), std::ios::out);
output << "Hi, I am " << m_start << std::endl;
output.close();
std::cout << "Thread # "
<< boost::this_thread::get_id()
<< " work finished!" << std::endl;
}
And the main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include "parallel.hpp"
int main(int argc, char* argv[]){
std::cout << "main: startup!" << std::endl;
std::cout << boost::thread::hardware_concurrency() << std::endl;
parallel p;
int populationSize(11), concurrency(3);
// define concurrent thread group
std::vector<boost::shared_ptr<boost::thread> > threads;
// population one-by-one
while(populationSize >= 0) {
// concurrent threads
for(int i = 0; i < concurrency; i++){
// create a thread
boost::shared_ptr<boost::thread>
thread(new boost::thread(¶llel::run, &p, populationSize--));
threads.push_back(thread);
}
// run the threads
for(int i =0; i < concurrency; i++)
threads[i]->join();
threads.clear();
}
return 0;
}
You have a single parallel object with a single m_start member variable, which all threads access without any synchronization.
Update
This race condition seems to be a consequence of a design problem. It is unclear what an object of type parallel is meant to represent.
If it is meant to represent a thread, then one object should be allocated for each thread created. The program as posted has a single object and many threads.
If it is meant to represent a group of threads, then it should not keep data that belongs to individual threads.
I am trying an example, which causes race condition to apply the mutex. However, even with the mutex, it still happens. What's wrong? Here is my code:
#include <iostream>
#include <boost/thread.hpp>
#include <vector>
using namespace std;
class Soldier
{
private:
boost::thread m_Thread;
public:
static int count , moneySpent;
static boost::mutex soldierMutex;
Soldier(){}
void start(int cost)
{
m_Thread = boost::thread(&Soldier::process, this,cost);
}
void process(int cost)
{
{
boost::mutex::scoped_lock lock(soldierMutex);
//soldierMutex.lock();
int tmp = count;
++tmp;
count = tmp;
tmp = moneySpent;
tmp += cost;
moneySpent = tmp;
// soldierMutex.unlock();
}
}
void join()
{
m_Thread.join();
}
};
int Soldier::count, Soldier::moneySpent;
boost::mutex Soldier::soldierMutex;
int main()
{
Soldier s1,s2,s3;
s1.start(20);
s2.start(30);
s3.start(40);
s1.join();
s2.join();
s3.join();
for (int i = 0; i < 100; ++i)
{
Soldier s;
s.start(30);
}
cout << "Total soldier: " << Soldier::count << '\n';
cout << "Money spent: " << Soldier::moneySpent << '\n';
}
It looks like you're not waiting for the threads started in the loop to finish. Change the loop to:
for (int i = 0; i < 100; ++i)
{
Soldier s;
s.start(30);
s.join();
}
edit to explain further
The problem you saw was that the values printed out were wrong, so you assumed there was a race condition in the threads. The race in fact was when you printed the values - they were printed while not all the threads had a chance to execute
Based on this and your previous post (were it does not seem you have read all the answers yet). What you are looking for is some form of synchronization point to prevent the main() thread from exiting the application (because when the main thread exits the application all the children thread die).
This is why you call join() all the time to prevent the main() thread from exiting until the thread has exited. As a result of your usage though your loop of threads is not parallel and each thread is run in sequence to completion (so no real point in using the thread).
Note: join() like in Java waits for the thread to complete. It does not start the thread.
A quick look at the boost documentation suggests what you are looking for is a thread group which will allow you to wait for all threads in the group to complete before exiting.
//No compiler so this is untested.
// But it should look something like this.
// Note 2: I have not used boost::threads much.
int main()
{
boost::thread_group group;
boost::ptr_vector<boost::thread> threads;
for(int loop = 0; loop < 100; ++loop)
{
// Create an object.
// With the function to make it start. Store the thread in a vector
threads.push_back(new boost::thread(<Function To Call>));
// Add the thread to the group.
group.add(threads.back());
}
// Make sure main does not exit before all the threads have completed.
group.join_all();
}
If we go back to your example and retrofit your Soldier class:
int main()
{
boost::thread batallion;
// Make all the soldiers part of a group.
// When you start the thread make the thread join the group.
Soldier s1(batallion);
Soldier s2(batallion);
Soldier s3(batallion);
s1.start(20);
s2.start(30);
s3.start(40);
// Create 100 soldiers outside the loo
std::vector<Soldier> lotsOfSoldiers;
lotsOfSoldiers.reserve(100); // to prevent reallocation in the loop.
// Because you are using objects we need to
// prevent copying of them after the thread starts.
for (int i = 0; i < 100; ++i)
{
lotsOfSoldiers.push_back(Solder(batallion));
lotsOfSoldiers.back().start(30);
}
// Print out values while threads are still running
// Note you may get here before any thread.
cout << "Total soldier: " << Soldier::count << '\n';
cout << "Money spent: " << Soldier::moneySpent << '\n';
batallion.join_all();
// Print out values when all threads are finished.
cout << "Total soldier: " << Soldier::count << '\n';
cout << "Money spent: " << Soldier::moneySpent << '\n';
}