I have a code, and i'm testing how much time will take an executing of 10 threads.
#include <iostream>
#include <thread>
#include <chrono>
#include <time.h>
using namespace std;
void pause_thread(int n){
this_thread::sleep_for(chrono::seconds(n));
cout << "pause of " << n << " seconds ended\n";
}
int main(){
clock_t EndTime = clock();
thread threads[10];
cout << "Spawning 10 threads...\n";
for (int i = 0; i<10; ++i)
threads[i] = thread(pause_thread, i + 1);
cout << "Done spawning threads. Now waiting for them to join:\n";
for (int i = 0; i<10; ++i)
threads[i].join();
cout << "All threads joined!\n";
cout << "==================================================\n";
cout << "Time of executing threads: " << (double)(clock() - EndTime) / CLOCKS_PER_SEC << endl;
system("pause");
return 0;
}
The output is this:
Spawning 10 threads...
Done spawning threads. Now waiting for them to join:
pause of 1 seconds ended
pause of 2 seconds ended
pause of 3 seconds ended
pause of 4 seconds ended
pause of 5 seconds ended
pause of 6 seconds ended
pause of 7 seconds ended
pause of 8 seconds ended
pause of 9 seconds ended
pause of 10 seconds ended
All threads joined!
==================================================
Time of executing threads: 10.041
First question is: Why execution of the program takes 10,041 seconds if the pause between each thread is 1 second? What happened with the program and it took additional 0.041s on executing?
Second question is: Is this right way to execute thread in another thread?
threads[i] = thread(...);
Is this mean that thread is in the thread?
If not, how can it be done (to execute thread in another thread)?
First question is well answered by Brandon Haston's comment.
Answer to second question doesn't fit in a comment.
threads[i] = thread(...);
means that a std::thread has been created and its representative std::thread object has been assigned to a slot in your std::thread array. This raises a question I'm going to have to look into on my own later when I have a compiler to play with: What happened to the thread that was just overwritten?
Anyway, that new thread isn't inside another thread. Threads don't have any concept of ownership mutual. A process owns threads, but threads don't. A thread can start another thread. For example,
void pause_thread(int n){
this_thread::sleep_for(chrono::seconds(n));
cout << "pause of " << n << " seconds ended\n";
if (! cows_are_home)
{
thread newthread(pause_thread, 1);
newthread.detach();
}
}
Each new thread will wait about 1 second, then create a thread which will wait a second and create another thread, and this will go on until the cows come home.
Related
I was trying to create a bank system that has features for credit,deposit,transaction history etc. I wanted to add interest rate as well so I was thinking of adding it in after 10 seconds of delay but When I am using delay(like sleep()function). My whole program is delayed by 10 seconds. Is there a way for interest to be calculated in the background while my runtime of the code won't be affected?
If you need just single task to be run then there exists std::async, which allows to run a task (function call) in a separate thread.
As you need to delay this task then just use std::sleep_for or std::sleep_until to add extra delay within async call. sleep_for shall be used if you want to wait for certain amount of seconds, and sleep_until shall be used if you want to wait till some point in time, e.g. to sleep until 11:32:40 time is reached.
In code below you can see that Doing Something 1 is run before start of async thread, then thread starts, which is waiting for 2 seconds, same time Doing Something 2 is called. After that you may wish (if so) to wait for delayed task to be finished, for that you call res.get(), this blocks main thread till async thread is fully finished. Afterwards Doing Something 3 is called.
If you don't do res.get() explicitly then async thread just finishes by itself at some point. Of if program is about to exit while async thread is still running, then program waits for this async thread to finish.
Try it online!
#include <future>
#include <chrono>
#include <thread>
#include <iostream>
#include <iomanip>
int main() {
int some_value = 123;
auto const tb = std::chrono::system_clock::now();
auto Time = [&]{
return std::chrono::duration_cast<std::chrono::duration<double>>(
std::chrono::system_clock::now() - tb).count();
};
std::cout << std::fixed << std::setprecision(3);
std::cout << "Doing Something 1... at "
<< Time() << " sec" << std::endl;
auto res = std::async(std::launch::async, [&]{
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "Doing Delayed Task... at "
<< Time() << " sec, value " << some_value << std::endl;
});
std::cout << "Doing Something 2... at "
<< Time() << " sec" << std::endl;
res.get();
std::cout << "Doing Something 3... at "
<< Time() << " sec" << std::endl;
}
Output:
Doing Something 1... at 0.000 sec
Doing Something 2... at 0.000 sec
Doing Delayed Task... at 2.001 sec, value 123
Doing Something 3... at 2.001 sec
I have a sample code:
#include <iostream> // std::cout
#include <thread> // std::thread
void pause_thread(int n)
{
if(n != 4)
{
std::this_thread::sleep_for(std::chrono::seconds(100));
std::cout << "pause of " << 100 << " seconds ended\n";
}
std::cout << "Thread number " << n << " ended\n";
}
int main()
{
std::thread threads[6]; // default-constructed threads
std::setvbuf(stdout, NULL, _IONBF, 0);
std::cout << "Spawning 5 threads...\n";
for(int i = 0; i < 5; ++i)
{
//If the object is currently not joinable, it acquires the thread of execution represented by rhs (if any).
//If it is joinable, terminate() is called. If it is joinable, terminate() is called.
//rhs no longer represents any thread of execution
threads[i] = std::move(std::thread(pause_thread, i)); // move-assign threads
}
std::thread& i = threads[4];
threads[5] = std::move(threads[4]);
std::cout << "Done spawning threads. Now waiting for them to join:\n";
for(int i = 0; i < 6; ++i)
{
if(threads[i].joinable())
{
std::cout << "Thread " << i << " " << threads[i].get_id() << " ID joinable" << std::endl << std::flush;
threads[i].join();
}
else
{
std::cout << "Thread " << i << " not joinable" << std::endl << std::flush;
}
}
std::cout << "All threads joined!\n";
return 0;
}
Below is the output I received:
Spawning 5 threads...
Done spawning threads. Now waiting for them to join:
Thread 0 22476 ID joinable
Thread number 4 ended
.... no output for 100 seconds ..
pause of 100 seconds ended
Thread number 0 ended
pause of 100 seconds ended
Thread 1 28676 ID joinable
pause of 100 seconds ended
Thread number 2 ended
Thread number 3 ended
pause of 100 seconds ended
Thread number 1 ended
Thread 2 2336 ID joinable
Thread 3 42236 ID joinable
Thread 4 not joinable
Thread 5 35940 ID joinable
All threads joined!
How the "Thread n xxxx ID joinable" statements are getting printed after "Thread number n ended"? I have even tried using set std::output as non buffered but the output was same?
"Joinable" does not imply that the thread is still executing.
You first join thread #0. This will take ~100 seconds.
During that time, thread #4 finishes since it doesn't sleep, and the other threads are sleeping.
If the threads happen to be scheduled differently, any of the "sleep threads" could be printing that they've ended here.
Once the wait for thread #0 is over, you start joining the other threads.
Some of these have finished executing before you join them and some haven't.
In this particular instance, none of them finished before the wait for thread #0 was over, but there is no guarantee of that happening.
And note that a line like
std::cout << "Thread number " << n << " ended\n";
is not atomic and characters from different threads can be interleaved.
Because joinable does not mean what you think : https://en.cppreference.com/w/cpp/thread/thread/joinable
So any thread that is started is "joinable" it does not need to have finished running.
I'm trying to understand how multi-threading works.
I have this code:
#include <iostream>
#include <thread>
#include <chrono>
void function1() {
std::cout << "Hi I'm the function 1" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Hi I'm the function 1 after sleeping" << std::endl;
}
void function2() {
std::cout << "Hi I'm the function 2" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "Hi I'm the function 2 after sleeping" << std::endl;
}
int main()
{
while(true) {
std::thread t1(function1);
std::thread t2(function2);
t1.join();
t2.join();
}
system("pause");
return 0;
}
And the problem is when I run it, it stops waiting for std::this_thread::sleep_for(std::chrono::seconds(5)); and doesn't show the next Hi I'm the function 1 from std::thread t1(function1); in the next loop, until the sleep thread ends.
1) Do you know why?
2) I want that the main continues the loop and don't wait to the t2 to finish (sleep_for() from function2 is set to 5 seconds)
This is what your code does:
Start thread 1
Outputs a message
Waits 1 second
Outputs another message
Start thread 2
Outputs a message
Waits 5 seconds
Outputs another message
Waits for both threads to finish
(this will take roughly 5 seconds)
Repeats indefinitely
You have stated that this isn't what you meant to do.
I think, instead, you intended to have the "repeat" inside of each thread, so that they continue ticking independently and indefinitely, like this:
#include <iostream>
#include <thread>
#include <chrono>
void function1() {
while (true) {
std::cout << "Hi I'm the function 1" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Hi I'm the function 1 after sleeping" << std::endl;
}
}
void function2() {
while (true) {
std::cout << "Hi I'm the function 2" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "Hi I'm the function 2 after sleeping" << std::endl;
}
}
int main()
{
std::thread t1(function1);
std::thread t2(function2);
t1.join();
t2.join();
}
Now your code does this:
Start thread 1
Outputs a message
Waits 1 second
Outputs another message
Repeats indefinitely
Start thread 2
Outputs a message
Waits 5 seconds
Outputs another message
Repeats indefinitely
Waits for both threads to finish
(although neither ever will!)
With each thread now spinning independently, neither will ever "block" the other.
1) This is my output and seems what I expect:
Hi I'm the function 1
Hi I'm the function 2
Hi I'm the function 1 after sleeping
Hi I'm the function 2 after sleeping
Hi I'm the function 1
Hi I'm the function 2
Hi I'm the function 1 after sleeping
Hi I'm the function 2 after sleeping
Hi I'm the function 2
Hi I'm the function 1
Hi I'm the function 1 after sleeping
Hi I'm the function 2 after sleeping
Hi I'm the function 2
Hi I'm the function 1
Hi I'm the function 1 after sleeping
Hi I'm the function 2 after sleeping
Hi I'm the function 2
Hi I'm the function 1
2) What you means for best performace???? sleep_for() works everywhere while Sleep is windows specific....
I suggest to use std library where you can, where put sleeps depends on your context...
When you join a thread it will complete its execution and exit. Hence when you joins your thread t1.join(); and t2.join();, the second statement will execute only when first join statement completed. So in your case to crease thread continuously and execute parallel you have to detach the threads like below:-
int i = 0;
while(true) {
std::thread t1(function1);
std::thread t2(function2);
t1.detach();
t2.detach();
//also break your infinite loop here
if( ++i < 4)
break;
}
Let's say there's a number of threads that consist of a loop running instances of the same function, but the start of every iteration needs to be synchronized (so the threads that finish first have to wait for the last one to begin a new iteration). How can this be done in c++11?
...
The rest of the post is just what I've tried and how it fails.
I'm using a counter, "sync", initially set to 3 (the number of threads). Every thread, at the end of the function will subtract 1 from this counter and start waiting. When the counter reaches 0, that means that the 3 of them have finished one round, so the main thread will reset the counter to 3 and notify the threads to wake them up.
This works most of the time but sometimes one or two of the threads fail to wake up.
So these are the global variables:
mutex syncMutex;
condition_variable syncCV;
int sync;
This is at the end of the function that runs in a loop in the threads:
unique_lock<mutex> lk(syncMutex);
cout << "Thread num: " << mFieldNum << " got sync value: " << sync;
sync --;
syncCV.notify_all();
cout << " and goes to sleep..." << endl;
syncCV.wait(lk, []{return sync == numFields;});
cout << "Thread num: " << mFieldNum << " woke up" << endl;
}
And this runs in a loop in the main thread:
unique_lock<mutex> lk(syncMutex);
syncCV.wait(lk, []{return sync == 0;});
sync = 3;
lk.unlock();
cout << "Notifying all threads!" << endl;
syncCV.notify_all();
This is the output it produces when it fails (thread #3 doesn't wake up):
Thread num: 1 got sync value: 3 and goes to sleep...
Thread num: 2 got sync value: 2 and goes to sleep...
Thread num: 3 got sync value: 1 and goes to sleep...
Notifying all threads!
Thread num: 1 woke up
Thread num: 2 woke up
Thread num: 3 woke up
Thread num: 2 got sync value: 3 and goes to sleep...
Thread num: 1 got sync value: 2 and goes to sleep...
Thread num: 3 got sync value: 1 and goes to sleep...
Notifying all threads!
Thread num: 2 woke up
Thread num: 1 woke up
Thread num: 2 got sync value: 3 and goes to sleep...
Thread num: 1 got sync value: 2 and goes to sleep...
Does anyone have a clue? Thank you for reading.
There are a number of issues with your thread synchronization. Tony has mentioned one in his comment. You also have a potential race condition in your main loop code where you call lk.unlock() before calling syncCV.notify_all(). (This could permit a thread to miss the notify_all signal.)
I would adjust your code in two ways. First, to address the use of "sync == numFields" as your condition, which, as Tony noted, can fail to be true after another thread has executed sync--, it makes sense to use as your condition that each thread run only once per main-thread loop. In my example code, this is achieved by introducing the "done[numFields]" variables. Second, it makes sense to introduce two condition variables -- one to signal the worker threads that a new main-loop iteration has started, and a second to signal the main thread that the worker threads are done. (Notice that the two condition variables use the same mutex.)
Here is a complete program, modelled on your sample code, that incorporates these two approaches:
#include <iostream>
using std::cout;
using std::endl;
#include <condition_variable>
#include <mutex>
#include <thread>
#include <vector>
std::mutex syncMutex;
std::condition_variable readyCV;
std::condition_variable doneCV;
int sync;
bool exitFlag;
const int numFields = 5;
bool done[numFields];
const int nloops = 10;
void thread_func(int i) {
int mFieldNum = i;
while (true) {
std::unique_lock<std::mutex> lk(syncMutex);
readyCV.wait(lk, [mFieldNum]{return exitFlag || !done[mFieldNum-1];});
if (exitFlag) break;
cout << "Thread num: " << mFieldNum << " woke up, got sync value: " << sync;
if (--sync == 0) doneCV.notify_all();
done[mFieldNum-1] = true;
readyCV.notify_all();
cout << " and goes to sleep..." << endl;
}
}
int main (int argc, char* argv[]) {
exitFlag = false;
sync = 0;
std::vector<std::thread> threads;
for (int i = 0; i < numFields; i++) {
done[i] = true;
threads.emplace_back (thread_func, i+1);
}
for (int i = 0; i <= nloops; i++) {
std::unique_lock<std::mutex> lk(syncMutex);
doneCV.wait(lk, []{return sync == 0;});
cout << "main loop (lk held), i = " << i << endl;
sync = numFields;
if (i == nloops) exitFlag = true;
else for (auto &b : done) b = false;
cout << "Notifying all threads!" << endl;
readyCV.notify_all();
}
for (auto& t : threads) t.join();
}
(I've also added an exitFlag and std::thread::join()'s so the program can clean up and terminate nicely.)
This is very similar to a classic producer-consumer implementation (one producer, numFields consumers), with the added constraint that each consumer thread will run only once per producer thread loop.
You can also achieve essentially the same program logic more simply if you are willing to forgo reusing the worker threads. (In your sample code and my above example, they are acting as a sort of specialized thread pool.) In my next example, new threads are created for each iteration of the main loop. This makes the thread synchronization simpler and eliminates the condition variables.
#include <iostream>
using std::cout;
using std::endl;
#include <atomic>
#include <mutex>
#include <thread>
#include <vector>
std::mutex coutMutex;
std::atomic<int> sync;
const int numFields = 5;
bool done[numFields];
const int nloops = 10;
void thread_func(int i) {
int mFieldNum = i;
int mySync = sync--;
{
std::lock_guard<std::mutex> lk(coutMutex);
cout << "Thread num: " << mFieldNum << " woke up, got sync value: " << mySync << endl;
}
}
int main (int argc, char* argv[]) {
for (int i = 0; i < nloops; i++) {
cout << "main loop, i = " << i << endl;
std::vector<std::thread> threads;
sync = numFields;
for (int i = 0; i < numFields; i++) threads.emplace_back (thread_func, i+1);
for (auto& t : threads) t.join();
}
}
(coutMutex is a nicety so that the console output doesn't get garbled, but it is not necessary for the core synchronization logic.)
If in your real-world use case you don't need the thread_func to stay alive from iteration to iteration (for example, to preserve some state), and if each call to thread_func does enough work that the cost of creating a new thread to run it doesn't really matter in comparison, then creating new threads for each main-loop iteration (instead of reusing threads) is straightforward, sensible, and simpler.
Happy Multi-Threaded Hacking!
K. Frank
I'm running a couple of threads in parallel. And I want to measure the time it takes to execute one thread and the time it takes to execute the whole program. I'm using VC++, on Windows 7.
I tried to measure it while debugging but then I saw this question: https://stackoverflow.com/questions/38971267/improving-performance-using-parallelism-in-c?noredirect=1#comment65299718_38971267 and in the answer given by Schnien it says:
Debugging of multiple threads is somehow "special" - when your Debugger halts at a breakpoint, the other threads will not be stopped - they will go on
Is this true ? And if yes how can I otherwise measure the time
Thanks
That statement is indeed true, only the thread that hits a breakpoint will be paused.
However to measure execution times you do not have to use debugging at all. More information on measuring execution time can be found on the below question:
Measure execution time in C (on Windows)
What you would want to do is measure the time inside the threads' functions (by subtracting the time at the beginning and at the end of the functions). You can do the same with the program, you can use thread.join to make sure all the threads executions end before measuring the time one last time.
Use a simple timer class to create a stopwatch capability then capture the time within each thread. Also, creating system threads is slower than using std::async and the latter can both return values and propagate exceptions which, using threads cause program termination unless caught within the thread.
#include <thread>
#include <iostream>
#include <atomic>
#include <chrono>
#include <future>
// stopwatch. Returns time in seconds
class timer {
public:
std::chrono::time_point<std::chrono::high_resolution_clock> lastTime;
timer() : lastTime(std::chrono::high_resolution_clock::now()) {}
inline double elapsed() {
std::chrono::time_point<std::chrono::high_resolution_clock> thisTime=std::chrono::high_resolution_clock::now();
double deltaTime = std::chrono::duration<double>(thisTime-lastTime).count();
lastTime = thisTime;
return deltaTime;
}
};
// for exposition clarity, generally avoid global varaibles.
const int count = 1000000;
double timerResult1;
double timerResult2;
void f1() {
volatile int i = 0; // volatile eliminates optimization removal
timer stopwatch;
while (i++ < count);
timerResult1=stopwatch.elapsed();
}
void f2() {
volatile int i = 0; // volatile eliminates optimization removal
timer stopwatch;
while (i++ < count);
timerResult2=stopwatch.elapsed();
}
int main()
{
std::cout.precision(6); std::cout << std::fixed;
f1(); std::cout << "f1 execution time " << timerResult1 << std::endl;
timer stopwatch;
{
std::thread thread1(f1);
std::thread thread2(f2);
thread1.join();
thread2.join();
}
double elapsed = stopwatch.elapsed();
std::cout << "f1 with f2 execution time " << elapsed << std::endl;
std::cout << "thread f1 execution time " << timerResult1 << std::endl;
std::cout << "thread f1 execution time " << timerResult2 << std::endl;
{
stopwatch.elapsed(); // reset stopwatch
auto future1 = std::async(std::launch::async, f1); // spins a thread and descturctor automatically joins
auto future2 = std::async(std::launch::async, f2);
}
elapsed = stopwatch.elapsed();
std::cout << "async f1 with f2 execution time " << elapsed << std::endl;
std::cout << "async thread f1 execution time " << timerResult1 << std::endl;
std::cout << "async thread f1 execution time " << timerResult2 << std::endl;
}
On my machine creating threads adds about .3 ms per thread whereas async is only about .05 ms per thread as it is implemented with a thread pool.
f1 execution time 0.002076
f1 with f2 execution time 0.002791
thread f1 execution time 0.002018
thread f1 execution time 0.002035
async f1 with f2 execution time 0.002131
async thread f1 execution time 0.002028
async thread f1 execution time 0.002018
[EDIT] Had incorrect f calls in front of statements (cut and past error)