WaitForSeconds functions in cpp - c++

Is there a function in C++ that delays the function it is running in for an amount of time, similar to WaitForSeconds in C#? I am aware of Sleep, but that pauses the entire program, I only want to pause a single function.

It depends on your programs architecture, if you let the function run on its own thread then yes you can use std::this_thread::sleep_for function to pause that function without affecting the whole program e.g.
void mythread()
{
int sum = 0;
for(int i = 0; i < 10; ++i)
{
std::this_thread::sleep_for(1s);
sum += i;
}
return sum;
}
int main()
{
std::future<int> result = new std::async(mythread);
// do something else
// ...
result.get();
}

Related

Let main thread wait async threads complete

I'm new to c++ and don't know how to let main thread wait for all async threads done. I refered this but makes void consume() not parallel.
#include <iostream>
#include <vector>
#include <unistd.h> // sleep
#include <future>
using namespace std;
class Myclass {
private:
std::vector<int> resources;
std::vector<int> res;
std::mutex resMutex;
std::vector<std::future<void>> m_futures;
public:
Myclass() {
for (int i = 0; i < 10; i++) resources.push_back(i); // add task
res.reserve(resources.size());
}
void consume() {
for (int i = 0; i < resources.size(); i++) {
m_futures.push_back(std::async(std::launch::async, &Myclass::work, this, resources[i]));
// m_futures.back().wait();
}
}
void work(int x) {
sleep(1); // Simulation time-consuming
std::lock_guard<std::mutex> lock(resMutex);
res.push_back(x);
printf("%d be added.---done by %d.\n", x, std::this_thread::get_id());
}
std::vector<int> &getRes() { return res;}
};
int main() {
Myclass obj;
obj.consume();
auto res = obj.getRes();
cout << "Done. res.size = " << res.size() << endl;
for (int i : res) cout << i << " ";
cout <<"main thread over\n";
}
Main thread ends up when res = 0. I want obj.getRes() be be executed when all results be added into res.
Done. res.size = 0
main thread over
4 be added.---done by 6.
9 be added.---done by 11...
You had the right idea with the commented out line: m_futures.back().wait();, you just have it in the wrong place.
As you note, launching a std::async and then waiting for its result right after, forces the entire thing to execute in series and makes the async pointless.
Instead you want two functions: One, like your consume() that launches all the async's, and then another that loops over the futures and calls wait (or get, whatever suits your needs) on them - and then call that from main.
This lets them all run in parallel, while still making main wait for the final result.
Addition to #Frodyne 's answer,
consume() function calls are parallel, and main thread waits for the all consume() s have their work done;
void set_wait(void)
{
for (int i = 0; i < resources.size(); i++) {
m_futures[i].wait();
}
}
And call it here
void consume() {
for (int i = 0; i < resources.size(); i++) {
m_futures.push_back(std::async(std::launch::async, &Myclass::work, this, resources[i]));
// Calling wait() here makes no sense
}
set_wait(); // Waits for all threads do work
}
I created new function for convenience.
You can use std::future:wait after you add task to m_futures. Example.
void consume() {
for (int i = 0; i < resources.size(); i++) {
m_futures.push_back(std::async(std::launch::async, &Myclass::work, this, resources[i]));
//m_futures.back().wait();
}
for(auto& f: m_futures) f.wait();
}

Threads with Classes and std::packaged_task

I'm trying to implement this Thread Pool with classes in C++.
Since now I was confident to have understand how classes work but now I'm getting mad.
I have 2 files
"JobScheduler.h" and "JobScheduler.cpp"
JobScheduler.h
class JobScheduler {
int thread_id;
std::vector<std::thread> pool;
std::mutex m1;
int set_id();
public:
JobScheduler();
~JobScheduler();
void Start();
};
JobScheduler.cpp
int id = 0;
std::mutex m;
JobScheduler::JobScheduler() {...}
JobScheduler::~JobScheduler() {...}
int JobScheduler::set_id() {
m1.lock();
int tmp_id = thread_id;
thread_id++;
std::cout << "id = " << tmp_id << "\n";
m1.unlock();
return tmp_id;;
}
int set_id_02(){
m.lock();
int tmp_id = id;
id++;
std::cout << "id = " << tmp_id << "\n";
m.unlock();
return tmp_id;
}
void JobScheduler::Start(){
// THIS DOESN'T WORK
/*
for(unsigned int i = 0; i < std::thread::hardware_concurrency(); i++){
pool.emplace_back(std::thread(std::packaged_task<void()>(JobScheduler::set_id))); // <--- error
}
... // print something and join threads
*/
// MANY THREADS - NO CLASS METHOD AS FUNCTION AND GLOBAL CPP VARIABLE - WORK
/*
for(unsigned int i = 0; i < std::thread::hardware_concurrency(); i++){
pool.emplace_back(std::thread(std::packaged_task<int()>(set_id_02)));
}
... // print something and join threads
*/
}
now if I use a function defined in .cpp it works fine but if I try to use a function I defined in the class it doesn't work but I need to be able to access Class variables.
So I have a lot of doubts:
1) why this doesn't work, what am I getting wrong?
2) it's ok to create a std::package_task like I do in the for? Or should I do something like
std::pakaged_task<int()> main_task(set_id);
for(unsigned int i = 0; i < std::thread::hardware_concurrency(); i++){
pool.emplace_back(std::thread(main_task));
}
3) in both cases how can I access the future of the task I created?
1) It's not working because you are creating the packaged task wrongly.
Since you are trying to use a member function you have to specify which object is going to be used to call those functions so you can try different approaches
Bind the object with the member function
Use a lambda as a proxy
std::packaged_task<int()>(std::bind(&JobScheduler::set_id, this))
std::packaged_task<int()>([this]{ return set_id(); })
For the second function is enough to just pass the function since it's a "free" function
std::packaged_task<int()>(set_id_02);
2) See above
3) In order to access the results of your packaged_task you must store its future
std::vector<std::future<int>> results;
for(unsigned int i = 0; i < std::thread::hardware_concurrency(); i++){
auto task = std::packaged_task<int()>([this]{ return set_id(); });
results.emplace_back(task.get_future());
pool.emplace_back(std::thread(std::move(task)));
}
//Access results
for (auto& f : results) {
cout << f.get() << endl;
}
As you rightly say, the problem is that you have to provide the object on which you want to call the member function. I see two solutions for that
// 1st wrap in a lambda
for(unsigned int i = 0; i < std::thread::hardware_concurrency(); i++){
pool.emplace_back(std::thread(std::packaged_task<void()>([this](){this->set_id();})));
}
// 2nd Use std::mem_fn and std::bind
for(unsigned int i = 0; i < std::thread::hardware_concurrency(); i++){
pool.emplace_back(std::thread(std::packaged_task<void()>(std::bind(std::mem_fn(&JobScheduler::set_id), *this))));
}
The first one should be clear, I think. In the second, std::mem_fn creates a function f such that f(object) does object.set_id() and std::bind creates a function g such that g() does f(this).
I prefer the first solution. It is one of many cases where lambdas are much simpler than using bind.

QtConcurrent: why releaseThread and reserveThread cause deadlock?

In Qt 4.7 Reference for QThreadPool, we find:
void QThreadPool::releaseThread()
Releases a thread previously reserved by a call to reserveThread().
Note: Calling this function without previously reserving a thread
temporarily increases maxThreadCount(). This is useful when a thread
goes to sleep waiting for more work, allowing other threads to
continue. Be sure to call reserveThread() when done waiting, so that
the thread pool can correctly maintain the activeThreadCount().
See also reserveThread().
void QThreadPool::reserveThread()
Reserves one thread, disregarding activeThreadCount() and
maxThreadCount().
Once you are done with the thread, call releaseThread() to allow it to
be reused.
Note: This function will always increase the number of active threads.
This means that by using this function, it is possible for
activeThreadCount() to return a value greater than maxThreadCount().
See also releaseThread().
I want to use releaseThread() to make it possible to use nested concurrent map, but in the following code, it hangs in waitForFinished():
#include <QApplication>
#include <QMainWindow>
#include <QtConcurrentMap>
#include <QtConcurrentRun>
#include <QFuture>
#include <QThreadPool>
#include <QtTest/QTest>
#include <QFutureSynchronizer>
struct Task2 { // only calculation
typedef void result_type;
void operator()(int count) {
int k = 0;
for (int i = 0; i < count * 10; ++i) {
for (int j = 0; j < count * 10; ++j) {
k++;
}
}
assert(k >= 0);
}
};
struct Task1 { // will launch some other concurrent map
typedef void result_type;
void operator()(int count) {
QVector<int> vec;
for (int i = 0; i < 5; ++i) {
vec.push_back(i+count);
}
Task2 task;
QFuture<void> f = QtConcurrent::map(vec.begin(), vec.end(), task);
{
// with out releaseThread before wait, it will hang directly
QThreadPool::globalInstance()->releaseThread();
f.waitForFinished(); // BUG: may hang there
QThreadPool::globalInstance()->reserveThread();
}
}
};
int main() {
QThreadPool* gtpool = QThreadPool::globalInstance();
gtpool->setExpiryTimeout(50);
int count = 0;
for (;;) {
QVector<int> vec;
for (int i = 0; i < 40 ; i++) {
vec.push_back(i);
}
// launch a task with nested map
Task1 task; // Task1 will have nested concurrent map
QFuture<void> f = QtConcurrent::map(vec.begin(), vec.end(),task);
f.waitForFinished(); // BUG: may hang there
count++;
// waiting most of thread in thread pool expire
while (QThreadPool::globalInstance()->activeThreadCount() > 0) {
QTest::qSleep(50);
}
// launch a task only calculation
Task2 task2;
QFuture<void> f2 = QtConcurrent::map(vec.begin(), vec.end(), task2);
f2.waitForFinished(); // BUG: may hang there
qDebug() << count;
}
return 0;
}
This code will not run forever; it will hang in after many loops (1~10000), with all threads waiting for condition variable.
My questions are:
Why does it hang?
Can I fix it and keep the nested concurrent map?
dev env:
Linux version 2.6.32-696.18.7.el6.x86_64; Qt4.7.4; GCC 3.4.5
Windows 7; Qt4.7.4; mingw 4.4.0
The program hangs because of the race condition in QThreadPool when you try to deal with expiryTimeout. Here is the analysis in detail :
The problem in QThreadPool - source
When starting a task, QThreadPool did something along the lines of:
QMutexLocker locker(&mutex);
taskQueue.append(task); // Place the task on the task queue
if (waitingThreads > 0) {
// there are already running idle thread. They are waiting on the 'runnableReady'
// QWaitCondition. Wake one up them up.
waitingThreads--;
runnableReady.wakeOne();
} else if (runningThreadCount < maxThreadCount) {
startNewThread(task);
}
And the the thread's main loop looks like this:
void QThreadPoolThread::run()
{
QMutexLocker locker(&manager->mutex);
while (true) {
/* ... */
if (manager->taskQueue.isEmpty()) {
// no pending task, wait for one.
bool expired = !manager->runnableReady.wait(locker.mutex(),
manager->expiryTimeout);
if (expired) {
manager->runningThreadCount--;
return;
} else {
continue;
}
}
QRunnable *r = manager->taskQueue.takeFirst();
// run the task
locker.unlock();
r->run();
locker.relock();
}
}
The idea is that the thread will wait for a given amount of second for
a task, but if no task was added in a given amount of time, the thread
expires and is terminated. The problem here is that we rely on the
return value of runnableReady. If there is a task that is scheduled at
exactly the same time as the thread expires, then the thread will see
false and will expire. But the main thread will not restart any other
thread. That might let the application hang as the task will never be
run.
The quick workaround is to use a long expiryTime (30000 by default) and remove the while loop that waits for the threads expired.
Here is the main function modified, the program runs smoothly in Windows 7, 4 threads used by default :
int main() {
QThreadPool* gtpool = QThreadPool::globalInstance();
//gtpool->setExpiryTimeout(50); <-- don't set the expiry Timeout, use the default one.
qDebug() << gtpool->maxThreadCount();
int count = 0;
for (;;) {
QVector<int> vec;
for (int i = 0; i < 40 ; i++) {
vec.push_back(i);
}
// launch a task with nested map
Task1 task; // Task1 will have nested concurrent map
QFuture<void> f = QtConcurrent::map(vec.begin(), vec.end(),task);
f.waitForFinished(); // BUG: may hang there
count++;
/*
// waiting most of thread in thread pool expire
while (QThreadPool::globalInstance()->activeThreadCount() > 0)
{
QTest::qSleep(50);
}
*/
// launch a task only calculation
Task2 task2;
QFuture<void> f2 = QtConcurrent::map(vec.begin(), vec.end(), task2);
f2.waitForFinished(); // BUG: may hang there
qDebug() << count ;
}
return 0;
}
#tungIt's answer is good enough, I found the qtbug and fix commit, just for reference:
https://bugreports.qt.io/browse/QTBUG-3786
https://github.com/qt/qtbase/commit/a9b6a78e54670a70b96c122b10ad7bd64d166514#diff-6d5794cef91df41c39b5e7cc6b71d041

How to use thread-local storage with parallelism?

I'm trying to replace the usage of std::async with thread pooling. Currently, I'm trying to use boost::executors::basic_thread_pool. The problem, however, is that I have objects, which are not thread-safe to use.
A naive solution would be to make lots of copies, like this:
boost::executors::basic_thread_pool thread_pool;
void do_work() {
const auto computer = slow_creation();
std::vector<boost::future<result_t>> results;
for (int i = 0; i < 1000000; ++i)
{
results.push_back(boost::async(thread_pool, computer.deep_copy()));
}
// wait to complete
// use results
}
I want it to look something like this:
boost::executors::basic_thread_pool thread_pool;
void do_work() {
const auto computer = slow_creation();
std::vector<boost::future<result_t>> results;
for (int i = 0; i < 1000000; ++i)
{
results.push_back(boost::async(thread_pool,
[] {
thread_local (but_not_global) copy = computer.deep_copy();
return copy();
}
));
}
// wait to complete
// use results
}
How to do this with Boost or any other library? I would prefer a library-based solution, which has a decent implementation of thread pool.

dynamic thread creation in c++

This is my code for multi threading (This is not the actual code but parts of different files at one place where I feel I am doing something wrong)
//main function
Example ExampleObj;
for (int i=0;i<10;i++)
{
pthread_t *service_thread = new pthread_t;
pthread_create(service_thread, NULL,start,&ExampleObj);
}
//start function
void *start(void *a)
{
Example *h = reinterpret_cast<Example *>(a);
h->start1();
return 0;
}
class Example
{
public:
void start1()
{
std::cout <<"I am here \n";
}
};
Code is not giving any error but it's not coming to start1 function as well.
Please let me know if I am creating the threads correctly or not.
If not, then what is the correct way.
There is no code that stops your main() from terminating the process before your worker threads have completed.
main() should look something like:
int main() {
Example ExampleObj;
// Start threads.
pthread_t threads[10];
for(size_t i = 0; i < sizeof threads / sizeof *threads; ++i) {
pthread_create(threads + i, NULL,start,&ExampleObj);
}
// Wait for the threads to terminate.
for(size_t i = 0; i < sizeof threads / sizeof *threads; ++i) {
pthread_join(threads[i], NULL);
}
}