i can't use delay argument inside of thread t
void HelloWorldDelay(int Delay)
{
cout << "Hello World";
atomic<bool> abort(false);
thread t([&abort]() {
Sleep(Delay);
abort = true;
});
t.join();
cout << Delay << "Ms ";
}
how to use it inside of thread t?
Sleep(Delay)
void HelloWorldDelay(int Delay) {
std::cout << "Hello World";
std::atomic<bool> abort(false);
std::thread t([&]() {
std::this_thread::sleep_for(std::chrono::seconds(Delay));
abort = true;
});
t.join();
std::cout << Delay << "Ms ";
}
will do the capturing
I think you should invoke like this :
#include <iostream>
#include <fstream>
#include <thread>
#include <atomic>
using namespace std;
void HelloWorldDelay(int Delay)
{
cout << "Hello World";
atomic<bool> abort(false);
thread t([&abort](int delay) {
//sleep(Delay);
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
abort = true;
}, std::ref(Delay));
t.join();
cout << Delay << "Ms ";
}
int main()
{
HelloWorldDelay(3);
std::system("pause");
return 0;
}
Related
I have some code which I'm working on where a detached thread is spawned, does some work, and then should wait for a signal from main() before sending another signal back to main indicating that the thread has quit.
I'm fairly new to condition variables, however I have worked with some multi thread code before. (Mostly mutexes.)
This is what I tried to implement, but it doesn't behave the way I would have expected. (Likely I misunderstood something.)
The idea behind this is to pass a struct containing two flags to each detached thread. The first flag indicates that main() says "it is ok to exit, and drop off the end of the thread function". The second flag is set by the thread itself and signals to main() that the thread has indeed exited. (It's just to confirm the signal from main() is recieved ok and to send something back.)
#include <cstdlib> // std::atoi
#include <iostream>
#include <thread>
#include <vector>
#include <random>
#include <future>
#include <condition_variable>
#include <mutex>
struct ThreadStruct
{
int id;
std::condition_variable cv;
std::mutex m;
int ok_to_exit;
int exit_confirm;
};
void Pause()
{
std::cout << "Press enter to continue" << std::endl;
std::cin.get();
}
void detachedThread(ThreadStruct* threadData)
{
std::cout << "START: Detached Thread " << threadData->id << std::endl;
// Performs some arbitrary amount of work.
for(int i = 0; i < 100000; ++ i);
std::cout << "FINISH: Detached thread " << threadData->id << std::endl;
std::unique_lock<std::mutex> lock(threadData->m);
std::cout << "WAIT: Detached thread " << threadData->id << std::endl;
threadData->cv.wait(lock, [threadData]{return threadData->ok_to_exit == 1;});
std::cout << "EXIT: Detached thread " << threadData->id << std::endl;
threadData->exit_confirm = 1;
}
int main(int argc, char** argv)
{
int totalThreadCount = 1;
ThreadStruct* perThreadData = new ThreadStruct[totalThreadCount];
std::cout << "Main thread starting " << totalThreadCount << " thread(s)" << std::endl;
for(int i = totalThreadCount - 1; i >= 0; --i)
{
perThreadData[i].id = i;
perThreadData[i].ok_to_exit = 0;
perThreadData[i].exit_confirm = 0;
std::thread t(detachedThread, &perThreadData[i]);
t.detach();
}
for(int i{0}; i < totalThreadCount; ++i)
{
ThreadStruct *threadData = &perThreadData[i];
std::cout << "Waiting for lock - main() thread" << std::endl;
std::unique_lock<std::mutex> lock(perThreadData[i].m);
std::cout << "Lock obtained - main() thread" << std::endl;
perThreadData[i].cv.wait(lock);
threadData->ok_to_exit = 1;
// added after comment from Sergey
threadData->cv.notify_all();
std::cout << "Done - main() thread" << std::endl;
}
for(int i{0}; i < totalThreadCount; ++i)
{
std::size_t thread_index = i;
ThreadStruct& threadData = perThreadData[thread_index];
std::unique_lock<std::mutex> lock(threadData.m);
std::cout << "i=" << i << std::endl;
int &exit_confirm = threadData.exit_confirm;
threadData.cv.wait(lock, [exit_confirm]{return exit_confirm == 1;});
std::cout << "i=" << i << " finished!" << std::endl;
}
Pause();
return 0;
}
This runs to the line:
WAIT: Detached thread 0
but the detached thread never quits. What have I done wrong?
Edit: Further experimentation - is this helpful?
I thought it might be helpful to simplify things by removing a step. In the example below, main() does not signal to the detached thread, it just waits for a signal from the detached thread.
But again, this code hangs - after printing DROP... This means the detached thread exits ok, but main() doesn't know about it.
#include <cstdlib> // std::atoi
#include <iostream>
#include <thread>
#include <vector>
#include <random>
#include <future>
#include <condition_variable>
#include <mutex>
struct ThreadStruct
{
int id;
std::condition_variable cv;
std::mutex m;
int ok_to_exit;
int exit_confirm;
};
void Pause()
{
std::cout << "Press enter to continue" << std::endl;
std::cin.get();
}
void detachedThread(ThreadStruct* threadData)
{
std::cout << "START: Detached Thread " << threadData->id << std::endl;
// Performs some arbitrary amount of work.
for(int i = 0; i < 100000; ++ i);
std::cout << "FINISH: Detached thread " << threadData->id << std::endl;
std::unique_lock<std::mutex> lock(threadData->m);
std::cout << "EXIT: Detached thread " << threadData->id << std::endl;
threadData->exit_confirm = 1;
threadData->cv.notify_all();
std::cout << "DROP" << std::endl;
}
int main(int argc, char** argv)
{
int totalThreadCount = 1;
ThreadStruct* perThreadData = new ThreadStruct[totalThreadCount];
std::cout << "Main thread starting " << totalThreadCount << " thread(s)" << std::endl;
for(int i = totalThreadCount - 1; i >= 0; --i)
{
perThreadData[i].id = i;
perThreadData[i].ok_to_exit = 0;
perThreadData[i].exit_confirm = 0;
std::thread t(detachedThread, &perThreadData[i]);
t.detach();
}
for(int i{0}; i < totalThreadCount; ++i)
{
std::size_t thread_index = i;
ThreadStruct& threadData = perThreadData[thread_index];
std::cout << "Waiting for mutex" << std::endl;
std::unique_lock<std::mutex> lock(threadData.m);
std::cout << "i=" << i << std::endl;
int &exit_confirm = threadData.exit_confirm;
threadData.cv.wait(lock, [exit_confirm]{return exit_confirm == 1;});
std::cout << "i=" << i << " finished!" << std::endl;
}
Pause();
return 0;
}
Your lambda is capturing by-value so it will never see the changes made to exit_confim.
Capture by-reference instead:
int& exit_confirm = threadData.exit_confirm;
threadData.cv.wait(lock, [&exit_confirm] { return exit_confirm == 1; });
// ^
// | capture by-reference
You also need to delete[] what you new[] so do
delete[] ThreadStruct;
when you're done with the the structs.
I also noticed some heap usage after free but that magically went away when I made some simplifications to the code. I didn't investigate that further.
Some suggestions:
Move code into the ThreadStruct class that deals with ThreadStruct member variables and locks. It usually makes it simpler to read and maintain.
Remove unused variables and headers.
Don't use new[]/delete[]. For this example, you could use a std::vector<ThreadStruct> instead.
Don't detach() at all - I haven't done anything about that below, but I suggest using join() (on attached threads) to do the final synchronization. That's what it's there for.
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
struct ThreadStruct {
int id;
// move this function into the ThreadStruct class
void detachedThread() {
std::cout << "START: Detached Thread " << id << std::endl;
// Performs some arbitrary amount of work (optimized away here)
std::cout << "FINISH: Detached thread " << id << std::endl;
std::lock_guard<std::mutex> lock(m);
std::cout << "EXIT: Detached thread " << id << std::endl;
exit_confirm = 1;
cv.notify_all();
std::cout << "DROP" << std::endl;
}
// add support functions instead of doing these things in your normal code
void wait_for_exit_confirm() {
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [this] { return exit_confirm == 1; });
}
void spawn_detached() {
std::thread(&ThreadStruct::detachedThread, this).detach();
}
private:
std::condition_variable cv;
std::mutex m;
int exit_confirm = 0; // initialize
};
With the above, main becomes a little cleaner:
int main() {
int totalThreadCount = 1;
std::vector<ThreadStruct> perThreadData(totalThreadCount);
std::cout << "Main thread starting " << perThreadData.size() << " thread(s)\n";
int i = 0;
for(auto& threadData : perThreadData) {
threadData.id = i++;
threadData.spawn_detached();
}
for(auto& threadData : perThreadData) {
std::cout << "Waiting for mutex" << std::endl;
std::cout << "i=" << threadData.id << std::endl;
threadData.wait_for_exit_confirm();
std::cout << "i=" << threadData.id << " finished!" << std::endl;
}
std::cout << "Press enter to continue" << std::endl;
std::cin.get();
}
For future interest: fixed the origional MWE posted in the question. There was two issues
not capturing local variable in lambda by reference (see other answer)
1 too many wait() calls
#include <cstdlib> // std::atoi
#include <iostream>
#include <thread>
#include <vector>
#include <random>
#include <future>
#include <condition_variable>
#include <mutex>
struct ThreadStruct
{
int id;
std::condition_variable cv;
std::mutex m;
int ok_to_exit;
int exit_confirm;
};
void Pause()
{
std::cout << "Press enter to continue" << std::endl;
std::cin.get();
}
void detachedThread(ThreadStruct* threadData)
{
std::cout << "START: Detached Thread " << threadData->id << std::endl;
// Performs some arbitrary amount of work.
for (int i = 0; i < 100000; ++i);
std::cout << "FINISH: Detached thread " << threadData->id << std::endl;
std::unique_lock<std::mutex> lock(threadData->m);
std::cout << "WAIT: Detached thread " << threadData->id << std::endl;
threadData->cv.wait(lock, [&threadData]{return threadData->ok_to_exit == 1;});
std::cout << "EXIT: Detached thread " << threadData->id << std::endl;
threadData->exit_confirm = 1;
threadData->cv.notify_all();
std::cout << "DROP" << std::endl;
}
int main(int argc, char** argv)
{
int totalThreadCount = 1;
ThreadStruct* perThreadData = new ThreadStruct[totalThreadCount];
std::cout << "Main thread starting " << totalThreadCount << " thread(s)" << std::endl;
for (int i = totalThreadCount - 1; i >= 0; --i)
{
perThreadData[i].id = i;
perThreadData[i].ok_to_exit = 0;
perThreadData[i].exit_confirm = 0;
std::thread t(detachedThread, &perThreadData[i]);
t.detach();
}
for(int i{0}; i < totalThreadCount; ++ i)
{
ThreadStruct *threadData = &perThreadData[i];
std::cout << "Waiting for lock - main() thread" << std::endl;
std::unique_lock<std::mutex> lock(perThreadData[i].m);
std::cout << "Lock obtained - main() thread" << std::endl;
//perThreadData[i].cv.wait(lock, [&threadData]{return threadData->ok_to_exit == 1;});
std::cout << "Wait complete" << std::endl;
threadData->ok_to_exit = 1;
threadData->cv.notify_all();
std::cout << "Done - main() thread" << std::endl;
}
for (int i{ 0 }; i < totalThreadCount; ++i)
{
std::size_t thread_index = i;
ThreadStruct& threadData = perThreadData[thread_index];
std::cout << "Waiting for mutex" << std::endl;
std::unique_lock<std::mutex> lock(threadData.m);
std::cout << "i=" << i << std::endl;
int& exit_confirm = threadData.exit_confirm;
threadData.cv.wait(lock, [&exit_confirm] {return exit_confirm == 1; });
std::cout << "i=" << i << " finished!" << std::endl;
}
Pause();
return 0;
}
I want to make a program which displays current time that ticks in background then is it possible to initialize cin input processes while it is ticking?
just for fun:
#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>
#include <mutex>
#include <ctime>
std::mutex more_lock;
std::string more_output;
void set_more_output(const std::string& more)
{
std::lock_guard<std::mutex> lock(more_lock);
more_output = more;
}
std::string get_more_output()
{
std::lock_guard<std::mutex> lock(more_lock);
return more_output;
}
std::atomic_bool running {true};
std::thread start_timer_runner()
{
return std::thread([&]{
while(running) {
using namespace std::chrono;
using namespace std::chrono_literals;
auto now = system_clock::to_time_t(system_clock::now());
auto now_str = std::string(std::ctime(&now));
now_str.pop_back(); // ctime adds new line
std::cout << "\r" << now_str << " | " << get_more_output() << std::flush;
std::this_thread::sleep_for(1s);
}
});
}
void parse_decimals()
{
int x;
set_more_output("please enter a decimal: ");
while(std::cin >> x)
{
set_more_output("thanks! you entered " + std::to_string(x) + ", please enter a new decimal: ");
}
}
int main()
{
auto timer = start_timer_runner();
parse_decimals();
running = false;
timer.join();
std::cout << std::endl << "bye bye!" << std::endl;
}
I've made a simple thread-safe Buffer implementation, creating 10 threads to work on the buffer queue to push and pop randomly some numbers. My implementation should let threads that are waiting to pop to wait only for 3 seconds and then terminate. When that occurs I print a timeout message.
The problem is that only one timeout message is printed, the main will then join all threads and return. Why?
Here is the code, main.cpp
#include <thread>
#include <vector>
#include <iostream>
#include <sstream>
#include "Buffer.h"
int main() {
std::vector<std::thread> workers;
Buffer<std::string> buffer(3);
srandom(time(NULL));
for (int i = 0; i < 10; i++) {
workers.emplace_back([&buffer]{
long num = random();
if(num%2==0) {
std::stringstream msg;
msg << std::this_thread::get_id() << " pushing " << num << std::endl;
std::cout << msg.str();
buffer.push(std::to_string(num));
} else {
std::stringstream msg1;
msg1 << std::this_thread::get_id() << " waiting to pop" << std::endl;
std::cout << msg1.str();
std::string popped_string = buffer.pop();
std::stringstream msg2;
msg2 << std::this_thread::get_id() << " popped " << popped_string << std::endl;
std::cout << msg2.str();
}
});
}
for (auto &w: workers) {
if (w.joinable()) w.join();
}
return 0;
}
Buffer.h
#ifndef PDS_CPP_BUFFER_H
#define PDS_CPP_BUFFER_H
#include <queue>
#include <mutex>
#include <condition_variable>
template <class T>
class Buffer {
private:
std::queue<T> queue;
std::mutex mutex;
std::condition_variable cv;
std::chrono::seconds sec;
public:
Buffer(int time) : sec(time), queue() {};
void push(T object) {
std::lock_guard lockGuard(mutex);
this->queue.push(object);
this->cv.notify_one();
}
T pop() {
std::unique_lock uniqueLock(mutex);
// this->cv.wait(uniqueLock, [this]{ return !this->queue.empty(); });
if(this->cv.wait_for(uniqueLock, this->sec, [this]{ return !this->queue.empty(); })) {
} else {
std::stringstream msg;
msg << std::this_thread::get_id() << " timeout" << std::endl;
std::cout << msg.str();
}
T object = this->queue.front();
this->queue.pop();
uniqueLock.unlock();
return object;
}
};
#endif //PDS_CPP_BUFFER_H
I am using C++11 on Mac OS Xcode 4.3.2
std::async uses same thread and my code does not achieve parallelism. In sample code below I want to create 10 new threads. In each thread I want to calculate square root of input variable and set the result in promise. in main function I want to display the results calculated from threads. I am calling std::async with policy launch::async, So I expect it to create a new thread(10 times).
#include <mutex>
#include <future>
#include <thread>
#include <vector>
#include <cmath>
#include <iostream>
using namespace std;
mutex iomutex;
void foo(int i, promise<double> &&prms)
{
this_thread::sleep_for(chrono::seconds(2));
prms.set_value(sqrt(i));
{
lock_guard<mutex> lg(iomutex);
cout << endl << "thread index=> " << i << ", id=> "<< this_thread::get_id();
}
}
int main()
{
{
lock_guard<mutex> lg(iomutex);
cout << endl << "main thread id=>"<< this_thread::get_id();
}
vector<future<double>> futureVec;
vector<promise<double>> prmsVec;
for (int i = 0; i < 10; ++i) {
promise<double> prms;
future<double> ftr = prms.get_future();
futureVec.push_back(move(ftr));
prmsVec.push_back(move(prms));
async(launch::async, foo, i, move(prmsVec[i]));
}
for (auto iter = futureVec.begin(); iter != futureVec.end(); ++iter) {
cout << endl << iter->get();
}
cout << endl << "done";
return 0;
}
However if I use std::thread, then I can achieve parallelism.
#include <mutex>
#include <future>
#include <thread>
#include <vector>
#include <cmath>
#include <iostream>
using namespace std;
mutex iomutex;
void foo(int i, promise<double> &&prms)
{
this_thread::sleep_for(chrono::seconds(2));
prms.set_value(sqrt(i));
{
lock_guard<mutex> lg(iomutex);
cout << endl << "thread index=> " << i << ", id=> "<< this_thread::get_id();
}
}
int main()
{
{
lock_guard<mutex> lg(iomutex);
cout << endl << "main thread id=>"<< this_thread::get_id();
}
vector<future<double>> futureVec;
vector<promise<double>> prmsVec;
vector<thread> thrdVec;
for (int i = 0; i < 10; ++i) {
promise<double> prms;
future<double> ftr = prms.get_future();
futureVec.push_back(move(ftr));
prmsVec.push_back(move(prms));
thread th(foo, i, move(prmsVec[i]));
thrdVec.push_back(move(th));
}
for (auto iter = futureVec.begin(); iter != futureVec.end(); ++iter) {
cout << endl << iter->get();
}
for (int i = 0; i < 10; ++i) {
thrdVec[i].join();
}
cout << endl << "done";
return 0;
}
async(launch::async, foo, i, move(prmsVec[i]));
This line returns a future but because you do not assign it to anything the future's destructor runs at the end of the statement, which blocks and waits for the result by calling std::future::wait()
Why are you manually calling std::async with a promise, when it returns a future anyway? The point of async is that you don't need to manually use a promise, that's done internally for you.
Rewrite your foo() to return double then call it with async
#include <mutex>
#include <future>
#include <thread>
#include <vector>
#include <cmath>
#include <iostream>
using namespace std;
mutex iomutex;
double foo(int i)
{
this_thread::sleep_for(chrono::seconds(2));
lock_guard<mutex> lg(iomutex);
cout << "\nthread index=> " << i << ", id=> "<< this_thread::get_id();
return sqrt(i);
}
int main()
{
cout << "\nmain thread id=>" << this_thread::get_id();
vector<future<double>> futureVec;
for (int i = 0; i < 10; ++i)
futureVec.push_back(async(launch::async, foo, i));
for (auto& fut : futureVec)
{
auto x = fut.get();
lock_guard<mutex> lg(iomutex);
cout << endl << x;
}
cout << "\ndone\n";
}
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <time.h>
using namespace std;
using namespace System;
void wait ( int seconds )
{
clock_t endwait;
endwait = clock() + seconds * CLOCKS_PER_SEC ;
while (clock() < endwait) {}
}
void timer()
{
int n;
printf ("Start\n");
for (n=10; n>0; n--) // n = time
{
cout << n << endl;
wait (1); // interval (in seconds).
}
printf ("DONE.\n");
system("PAUSE");
}
int main ()
{
timer();
cout << "test" << endl; // run rest of code here.}
return 0;
}
I'm trying to create a timer in C++ which would run in the background. So basically if you'd look at the 'main block' I want to run the timer (which is going to count down to 0) and at the same time run the next code, which in this case is 'test'.
As it is now the next line of code won't be run until the timer has finished. How do I make the timer run in the background?
Thanks for your help in advance!
C++11. Should work with VS11 beta.
#include <chrono>
#include <iostream>
#include <future>
void timer() {
std::cout << "Start\n";
for(int i=0;i<10;++i)
{
std::cout << (10-i) << '\n';
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "DONE\n";
}
int main ()
{
auto future = std::async(timer);
std::cout << "test\n";
}
If the operation performed in timer() takes significant time you can get better accuracy like this:
void timer() {
std::cout << "Start\n";
auto start = std::chrono::high_resolution_clock::now();
for(int i=0;i<10;++i)
{
std::cout << (10-i) << '\n';
std::this_thread::sleep_until(start + (i+1)*std::chrono::seconds(1));
}
std::cout << "DONE\n";
}