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++?
Related
I am trying to run run() function every 5 seconds without stopping while() loop (parallelly). How can I do that ? Thanks in advance
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
void run()
{
this_thread::sleep_for(chrono::milliseconds(5000));
cout << "good morning" << endl;
}
int main()
{
thread t1(run);
t1.detach();
while(1)
{
cout << "hello" << endl;
this_thread::sleep_for(chrono::milliseconds(500));
}
return 0;
}
In your main function, it is important to understand what each thread is doing.
The main thread creates a std::thread called t1
The main thread continues and detaches the thread
The main thread executes your while loop in which it:
prints hello
sleeps for 0.5 seconds
The main thread returns 0, your program is finished.
Any time from point 1, thread t1 sleeps for 5 seconds and then prints good morning. This happens only once! Also, as pointed out by #Fareanor, std::cout is not thread-safe, so accessing it with the main thread and thread t1 may result in a data race.
When the main thread reaches point 4 (it actually never does because your while loop is infinite), your thread t1 might have finished it's task or not. Imagine the potential problems that could occur. In most of the cases, you'll want to use std::thread::join().
To solve your problem, there are several alternatives. In the following, we will assume that the execution of the function run without the std::this_thread::sleep_for is insignificant compared to 5 seconds, as per the comment of #Landstalker. The execution time of run will then be 5 seconds plus some insignificant time.
As suggested in the comments, instead of executing the function run every 5 seconds, you could simply execute the body of run every 5 seconds by placing a while loop inside of that function:
void run()
{
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
std::cout << "good morning" << std::endl;
}
}
int main()
{
std::thread t(run);
t.join();
return 0;
}
If, for some reason, you really need to execute the run function every 5 seconds as stated in your question, you could launch a wrapper function or lambda which contains the while loop:
void run()
{
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
std::cout << "good morning" << std::endl;
}
int main()
{
auto exec_run = [](){ while (true) run(); };
std::thread t(exec_run);
t.join();
return 0;
}
As a side note, it's better to avoid using namespace std.
Just call your run function in seperate thread function like below. Is this ok for you?
void ThreadFunction()
{
while(true) {
run();
this_thread::sleep_for(chrono::milliseconds(5000));
}
}
void run()
{
cout << "good morning" << endl;
}
int main()
{
thread t1(ThreadFunction);
t1.detach();
while(1)
{
cout << "hello" << endl;
this_thread::sleep_for(chrono::milliseconds(500));
}
return 0;
}
I want to create a simple program that starts 5 threads that print "hello world! This is thread [thread number]".
Each print operation should be preceded by a random wait operation, to demonstrate that the threads are running concurrently. (The threads will print their message in a random order, as opposed to printing in order which would happen if the threads are running sequentially.)
Here is the code that should achieve this:
Poco::Thread thread[5];
class HelloRunnable: public Poco::Runnable
{
public:
HelloRunnable(int arg)
{
n = arg;
}
int n;
virtual void run()
{
usleep(rand()%100000);
std::cout << "Hello, world! This is thread " << n << std::endl;
}
};
int main()
{
for(int i=0; i<5; i++)
{
HelloRunnable runnable(i);
thread[i].start(runnable);
}
for(int i=0; i<5; i++)
{
thread[i].join();
}
return 0;
}
However, at run time, this gives the error:
//pure virtual method called
//terminate called without an active exception
//The program has unexpectedly finished.
If instead, I put thread[i].join() inside the same for loop as thread[i].start(), then the program runs without error but it prints the threads in order. (Becuase join() waits until the thread has finished before moving on, hence the threads are executed sequentially and not concurrently.
How can I make the threads run concurrently and print out the message to the standard output as soon as cout is called?
Since you create the objects inside the for loop their lifetime will end immediately after each iteration. This will cause issues. As the documentation for start() states:
Note that the given Runnable object must remain valid during the entire lifetime of the thread, as only a reference to it is stored internally.
You need to create the runnables in a way that keeps them alive outside the loop also.
As Sami has said, the runnable was destroyed before the thread had finished. I removed the for loops and typed each line out explicitly. I also removed a thread as I can only run 4 threads without causing a crash. Finally, I created a separate runnable for each thread, as in the original code each thread was using the same one.
Poco::Thread thread[5];
class HelloRunnable: public Poco::Runnable
{
public:
HelloRunnable(int arg)
{
n = arg;
}
int n;
virtual void run()
{
//sleep for random length of time
timeval t;
gettimeofday(&t, NULL);
srand(t.tv_usec * t.tv_sec);
int uS = rand()%100000;
usleep(uS);
//print message
std::cout << "Hello, world! This is thread " << n << " I slept for "<< uS << "uS" <<std::endl;
return;
}
};
int main()
{
HelloRunnable runnable1(1);
thread[1].start(runnable1);
HelloRunnable runnable2(2);
thread[2].start(runnable2);
HelloRunnable runnable3(3);
thread[3].start(runnable3);
HelloRunnable runnable4(4);
thread[4].start(runnable4);
thread[1].join();
thread[2].join();
thread[3].join();
thread[4].join();
return 0;
}
The thing is i want to use c++ library which runs different threads simultaneously without having other threads to wait until the preceding thread is complete and their functionality within each thread is run simultaneuslly,I am talking about the code which is to be run in the thread;the sample code is shown below.
while(condition is true<it is infinite loop >){
running sleep here with random time
sleep(random time(sec))
rest of the code is here
}
This infinite while loop is run in each thread. I want to run this while loop in each thread to be run simultaneously without being stuck at the first thread to be completed. In other words all the infinite while loop(in each thread context) is to be run simultaneously. How do I achieve that? If you can please share some sample code actually I have used future with async but I get the same behavior as normal <thread> using join().
The issue you are encountering is because of the rather silly definition of std::async (in my opinion) that it doesn't have to execute your code asynchronously, but can instead run it when you attempt to get from its std::future return value.
No matter. If you set the first parameter of your call to std::launch::async you force it to run asynchronously. You can then save the future in a container, and if you retire futures from this container regularly, you can run as many threads as the system will let you.
Here's an example:
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
#include <vector>
#include <mutex>
using future_store = std::vector<std::future<void>>;
void retireCompletedThreads(future_store &threadList)
{
for (auto i = threadList.begin(); i != threadList.end(); /* ++i */)
{
if (i->wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
i->get();
i = threadList.erase(i);
}
else
{
++i;
}
}
}
void waitForAllThreads(future_store &threadList)
{
for (auto& f : threadList)
{
f.get();
}
}
std::mutex coutMutex;
int main(int argc, char* argv[])
{
future_store threadList;
// No infinite loop here, but you can if you want.
// You do need to limit the number of threads you create in some way though,
// for example, only create new threads if threadList.size() < 20.
for (auto i = 0; i < 20; ++i)
{
auto f = std::async(std::launch::async,
[i]() {
{
std::lock_guard<std::mutex> l(coutMutex);
std::cout << "Thread " << i << " started" << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<std::mutex> l(coutMutex);
std::cout << "Thread " << i << " completed" << std::endl;
}
});
threadList.push_back(std::move(f));
// Existing threads need to be checked for completion every so often
retireCompletedThreads(threadList);
}
waitForAllThreads(threadList);
}
I am beginning to use the thread class.
In the main() thread below, an Example class is created.
Inside the constructor of Example, two threads are created in the Example::start() function.
Example::foo() is designed to print a message every second.
Example::bar() is designed to print a message every 5 seconds.
Inside the main() function, a loop is designed to print every 3 seconds.
I decided to not use join() in Example::start() because I would like to have the main() function continuously run.
Why does the main thread crash during run-time?
// thread example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
using namespace std;
class Example
{
public:
Example();
void start();
void foo();
void bar(int x);
};
Example::Example()
{
start();
}
void Example::start()
{
std::thread first (&Example::foo, this); // spawn new thread that calls foo()
std::thread second (&Example::bar, this, 5); // spawn new thread that calls bar(0)
// synchronize threads:
//first.join(); // pauses until first finishes
//second.join(); // pauses until second finishes
}
void Example::foo()
{
cout << "entered foo()" << endl;
int count = 0;
while(1) {
std::this_thread::sleep_for (std::chrono::seconds(1));
++count;
cout << "foo() count = " << count << endl;
}
}
void Example::bar(int x)
{
cout << "entered bar() x = " << x << endl;
int count = 0;
while(1) {
std::this_thread::sleep_for (std::chrono::seconds(5));
++count;
cout << "bar() count = " << count << endl;
}
}
int main() {
Example* c = new Example();
cout << "Example() created" << endl;
while(true) {
std::this_thread::sleep_for(std::chrono::seconds(3));
cout << "main() thread loop..." << endl;
}
std::cout << "end of main()";
delete c;
return 0;
}
Foo::Start() initalizes two threads, thread Foo and thread bar. When the function Start returns to the main thread, the two thread objects go out of scope and the destructor is called for clearing out of scope variables.
A simple solution would be to make threads part of the class.
On another note, std::cout is not a synchronized class, when writing your text might be garbled: Is cout synchronized/thread-safe?
Also, when creating your class Example, delete is never called which causes a memory leak.
Your comment here:
void Example::start()
{
std::thread first (&Example::foo, this); // spawn new thread that calls foo()
std::thread second (&Example::bar, this, 5); // spawn new thread that calls bar(0)
// synchronize threads:
//first.join(); // pauses until first finishes
//second.join(); // pauses until second finishes
}
Is wrong.
Not only does the the join pause until the threads finish. But they also allow the thread to be cleaned up. A thread destructor calls terminate while the thread is join-able (ie it is still running). So you must call join() on the thread (to wait for it to finish) before you can allow the destructor to be called.
One of the comments above suggests calling detach(). This detaches the thread of execution from the thread object (thus making it not join-able). This will work (as your code is in infinite loop), but is a bad idea generally. As allowing main() to exit while threads are still running is undefined behavior.
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';
}