Implementation with pthread works, but not with std::thread: a thread blocking my mainloop function - multithreading

I tried yesterday to use std::thread correctly, but it's very dark for me.
My program implementation with pthread works well I don't have any problem with it. I would like to have the same solution with std::thread (if possible).
Solution with pthread:
void *MyShell(void *data) {
std::string str;
while(1) {
std::cin >> str;
std::cout << str << std::endl;
}
}
void mainloop() {
pthread_t thread;
pthread_create(&thread, NULL, aed::map::shell::Shell, this);
...
pthread_cancel(thread);
}
And now the solution which doesn't work everytime, with std::thread:
class ShellThreadInterrupFlag {
public:
void interrupt() {
throw std::string("Thread interruption test\n");
}
};
class ShellThread {
public:
template<typename FunctionType, typename ParamsType>
ShellThread(FunctionType f, ParamsType params) {
std::promise<ShellThreadInterrupFlag *> p[3];
_internal_thread = new std::thread(f, p, params);
_flag = p[0].get_future().get();
_internal_thread->detach();
p[1].set_value(_flag); // tell the thread that we detached it
p[2].get_future().get(); // wait until the thread validates the constructor could end (else p[3] is freed)
}
~ShellThread() {
delete _internal_thread;
}
void interrupt() {
_flag->interrupt();
}
private:
std::thread *_internal_thread;
ShellThreadInterrupFlag *_flag;
};
void Shell(std::promise<ShellThreadInterrupFlag *> promises[3],
aed::map::MapEditor *me)
{
ShellThreadInterrupFlag flag;
promises[0].set_value(&flag); // give the ShellThread instance the flag adress
promises[1].get_future().get(); // wait for detaching
promises[2].set_value(&flag); // tell ShellThread() it is able to finish
while(1) {
std::cin >> str;
std::cout << str << std::endl;
}
}
void mainloop()
{
ShellThread *shell_thread;
shell_thread = new ShellThread(Shell, this);
... // mainloop with opengl for drawing, events gestion etc...
shell_thread->interrupt();
}
Sometimes, when I launch the program, the std::cin >> str is called and the mainloop is blocked.
Does anyone know why the thread is blocking my mainloop ? And how could I avoid this problem ?

Related

Using std::async in constructor

I am quite new to the C++11 feature std::async and I fail to grasp why the code below never prints bar.
Could someone shed some light on this for me?
class Thready {
public:
Thready() {
std::async(std::launch::async, &Thready::foo, this);
}
void foo() {
while (true) {
std::cout << "foo" << std::endl;
}
}
void bar() {
while (true) {
std::cout << "bar" << std::endl;
}
}
};
int main() {
Thready t;
t.bar();
}
See "Notes" section on this page: http://en.cppreference.com/w/cpp/thread/async
The implementation may extend the behavior of the first overload of
std::async by enabling additional (implementation-defined) bits in the
default launch policy. Examples of implementation-defined launch
policies are the sync policy (execute immediately, within the async
call) and the task policy (similar to async, but thread-locals are not
cleared) If the std::future obtained from std::async is not moved from
or bound to a reference, the destructor of the std::future will block
at the end of the full expression until the asynchronous operation
completes, essentially making code such as the following synchronous:
std::async(std::launch::async, []{ f(); }); // temporary's dtor waits for f()
std::async(std::launch::async, []{ g(); }); // does not start until f() completes
(note that the destructors of std::futures
obtained by means other than a call to std::async never block)
TL;DR:
try to save the returned value of std::async call into some variable:
auto handle = std::async(std::launch::async, &Thready::foo, this);
EDIT:
the following code should work as you expect.
#include <future>
#include <iostream>
class Thready {
public:
Thready() {
handle = std::async(std::launch::async, &Thready::foo, this);
}
void foo() {
while (true) {
std::cout << "foo" << std::endl;
}
}
void bar() {
while (true) {
std::cout << "bar" << std::endl;
}
}
std::future<void> handle;
};
int main() {
Thready t;
t.bar();
}

QT5 Cross-thread communication, slot not called in "this" context

I have an object MainWorker ran as a separate thread thanks to moveToThread method.
MainWorker has a member SubWorker which is also ran as a separate thread. Both threads are working in infinite loops.
The idea is, MainWorker and SubWorker both perform some separate computations. Whenever SubWorker is done computing, it should notify MainWorker with the result.
Therefore I intuitively made first connection between signal emitted by SubWorker and a slot of MainWorker, but it wasn't working, so I made two more connections to rule out some potential problems:
connect(subWorker, &SubWorker::stuffDid, this, &MainWorker::reportStuff)); //1
connect(subWorker, &SubWorker::stuffDid, subWorker, &SubWorker::reportStuff); //2
connect(this, &MainWorker::stuffDid, this, &MainWorker::reportStuffSelf); //3
It seems, that what is not working is exactly what I need - cross thread communication, because connection 2 and 3 works as expected. My question is: How do I make connection 1 work?
Edit: Apparently, after Karsten's explanation, it is clear that infinite loop blocks the EventLoop. So the new question is, how can I send messages (signals, whatever) from an infinite loop thread to its parent thread?
I am new to Qt, there is a high chance that I got it completely wrong. Here goes the minimal (not)working example:
MainWorker.h
class MainWorker : public QObject
{
Q_OBJECT
public:
MainWorker() : run(false) {}
void doStuff()
{
subWorker = new SubWorker;
subWorkerThread = new QThread;
subWorker->moveToThread(subWorkerThread);
connect(subWorkerThread, &QThread::started, subWorker, &SubWorker::doStuff);
if(!connect(subWorker, &SubWorker::stuffDid, this, &MainWorker::reportStuff)) qDebug() << "connect failed";
connect(subWorker, &SubWorker::stuffDid, subWorker, &SubWorker::reportStuff);
connect(this, &MainWorker::stuffDid, this, &MainWorker::reportStuffSelf);
subWorkerThread->start();
run = true;
while(run)
{
QThread::currentThread()->msleep(200);
emit stuffDid();
}
}
private:
bool run;
QThread* subWorkerThread;
SubWorker* subWorker;
signals:
void stuffDid();
public slots:
void reportStuff()
{
qDebug() << "MainWorker: SubWorker did stuff";
}
void reportStuffSelf()
{
qDebug() << "MainWorker: MainWorker did stuff (EventLoop is not blocked)";
}
};
SubWorker.h
class SubWorker : public QObject
{
Q_OBJECT
public:
SubWorker() : run(false) {}
void doStuff()
{
run = true;
while(run)
{
qDebug() << "SubWorker: Doing stuff...";
QThread::currentThread()->msleep(1000);
emit stuffDid();
}
}
private:
bool run;
public slots:
void reportStuff()
{
qDebug() << "SubWorker: SubWorker did stuff";
}
signals:
void stuffDid();
};
main.cpp
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MainWorker *mainWorker = new MainWorker;
QThread *mainWorkerThread = new QThread;
mainWorker->moveToThread(mainWorkerThread);
QObject::connect(mainWorkerThread, &QThread::started, mainWorker, &MainWorker::doStuff);
mainWorkerThread->start();
return a.exec();
}

C++11 joining the first thread that finished

Is there a way to start two (or more) C++11 threads and join() the first one that is finished?
An example scenario:
#include <iostream>
#include <thread>
using namespace std;
void prepare_item1() {std::cout << "Preparing 1" << std::endl;}
void consume_item1() {std::cout << "Consuming 1" << std::endl;}
void prepare_item2() {std::cout << "Preparing 2" << std::endl;}
void consume_item2() {std::cout << "Consuming 2" << std::endl;}
int main()
{
std::thread t1(prepare_item1);
std::thread t2(prepare_item2);
t1.join();
consume_item1();
t2.join();
consume_item2();
return 0;
}
I would have liked to do something like that instead:
int main()
{
std::thread t1(prepare_item1);
std::thread t2(prepare_item2);
finished_id=join_any(t1,t2)
if (finished_id==1)
{
consume_item1();
...
}
else if (finished_id==2)
{
consume_item2();
...
}
return 0;
}
Also, I would like the solution to be blocking, similar to the t.join() function.
Note: The real reason I need this is that I have two different blocking functions from which I receive commands, and whenever any of them is ready I would like to process the first command that arrives and continue to the next one when it is done. (sequential processing of commands from two parallel sources)
Thanks!
Here is a thread-safe multi-producer multi-consumer queue:
template<class T>
struct safe_queue {
std::deque<T> data;
std::atomic<bool> abort_flag = false;
std::mutex guard;
std::condition_variable signal;
template<class...Args>
void send( Args&&...args ) {
{
std::unique_lock<std::mutex> l(guard);
data.emplace_back(std::forward<Args>(args)...);
}
signal.notify_one();
}
void abort() {
abort_flag = true; // 1a
{ std::unique_lock<std::mutex>{guard}; }
signal.notify_all(); // 1b
}
std::experimental::optional<T> get() {
std::unique_lock<std::mutex> l(guard);
signal.wait( l, [this]()->bool{ // 2b
return !data.empty() || abort_flag.load(); // 2c
});
if (abort_flag.load()) return {};
T retval = std::move(data.front());
data.pop_front();
return retval;
}
};
have the threads shove data into the queue, and the main thread do a .get() on it.
If abort() is called, all waiting threads are woken up with an "empty" value from .get().
It uses std::experimental::optional, but you can replace that with something else (throw on abort? Whatever).
Code modified slightly from this other answer. Note that I think the other answer has some errors in it, which I corrected above, and attempts to solve a different problem.
The message you send could be the id of the thread that is ready to be waited upon, for example, or the work it has completed, or whatever.

How to send signal from Singleton thread to another thread (Not singleton)

I'm facing a problem while creating a Singleton class with it's own thread that sends signal to another thread which is not a singleton class.
Consumer.h
class Consumer : public QThread
{
Q_OBJECT
public:
explicit Consumer(QObject *parent = 0);
Consumer(Worker *Worker);
signals:
void toMessage(const bool& keepCycle);
public slots:
void getMessage(const QString& str);
private:
int m_counter;
};
Consumer.cpp
Consumer::Consumer(QObject *parent) :
QThread(parent)
{
m_counter = 0;
connect(Worker::Instance(), SIGNAL(sendMessage(QString)), this, SLOT(getMessage(QString)));
connect(this, SIGNAL(toMessage(bool)), Worker::Instance(), SLOT(fromMessage(bool)));
}
// Get's message from Singleton thread if counter > 5 sends signal to terminate cycle in Singleton thread
void Consumer::getMessage(const QString &str)
{
m_counter++;
if(m_counter <= 5) {
qDebug() << "Got message " << m_counter << ": " << str << "\n";
return;
}
else {
emit toMessage(false);
}
}
Singleton is done as follows (suspect it's Not Thread-safe):
template <class T>
class Singleton
{
public:
static T* Instance()
{
if(!m_Instance) m_Instance = new T;
assert(m_Instance != NULL);
return m_Instance;
}
protected:
Singleton();
~Singleton();
private:
Singleton(Singleton const&);
Singleton& operator=(Singleton const&);
static T* m_Instance;
};
template <class T> T* Singleton<T>::m_Instance = NULL;
And Worker Singleton class
class Worker : public QThread
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0);
void run();
signals:
void sendMessage(const QString& str);
public slots:
void fromMessage(const bool& keepCycle);
private:
volatile bool m_keepCycle;
};
typedef Singleton<Worker> Worker;
Worker.cpp
Worker::Worker(QObject *parent) :
QThread(parent)
{
m_keepCycle = true;
}
void Worker::run()
{
while(true) {
if(m_keepCycle) {
QString str = "What's up?";
ElWorker::Instance()->sendMessage(str);
}
else {
qDebug() << "Keep Alive" << false;
break;
}
}
qDebug() << "Value of keepCycle" << m_keepCycle;
}
void Worker::fromMessage(const bool &keepCycle)
{
m_keepCycle = keepCycle;
qDebug() << "\nMessage FROM: " << keepCycle << "\n";
}
The main.cpp
Consumer consumer;
ElWorker::Instance()->start();
consumer.start();
Can you help me to create thread-safe Singleton and to send signals between threads?
First of all, it is highly recommended to separate worker from it's thread:
class Object : public QObject
{
...
public slots:
void onStarted(); // if needed
void onFinished(); // if needed
...
};
...
mObject = QSharedPointer < Object >(new Object);
mThread = new QThread(this);
mObject->moveToThread(mThread);
connect(mThread, SIGNAL(started()), mObject, SLOT(onStarted())); // if needed
connect(mThread, SIGNAL(finished()), mObject, SLOT(onFinished())); // if needed
mThread->start();
Second of all, there are a lot of ways of creating a singleton. My favourite is this:
Object * obj(QObject *parent = 0)
{
static Object *mObj = new Object(parent);
return mObj;
}
...
obj(this); // creating
obj()->doStuff(); // using
Now, about thread-safety. Sending signals is thread-safe, unless you're sending pointers or non-constant references. Which, according to your code, you are not. So, you should be fine.
UPDATE
Actually, I didn't get how created thread-safe singleton above and I'm
sending a signal from Worker TO Consumer Not a Thread itself? – hiken
Static values inside of function are created and initialized only once, so the first time you call obj function mObj is created and returned and each other time you call it, previously created mObj is returned. Also, I didn't say, it's thread-safe, all I said - I like this way better, then template one, because:
it is simplier
requires less code
works with QObject without problems
Yes, you should send signals from worker class, not thread one. Qt's help has a good example (the first one, not the second one): http://doc.qt.io/qt-5/qthread.html#details. The only thing QThread should be used for - is controlling thread's flow. There are some situations, when you need to derive from QThread and rewrite QThread::run, but your case isn't one of them.

Synchronizing tasks

I am develeping an application that uses a threadpool, submits tasks to it and synchronizes them. The main thread has to wait until all the submitted tasks from a single loop iteration finish and then it submits another bunch of tasks (because the tasks from the next iteration operate on the same data and they will be dependent on one another).
My question is, what is the best way to do that?
So far, what I have come up with is that each thread, after finishing a task, increments an atomic unsigned integer. When the integer equals the number of submitted tasks, the main thread continues its work and submits another round of tasks.
This is my first multithreaded application.
Is this an optimal and sensible way of dealing with this problem.
I'm using a threadpool class copied from an excellent book "C++ Concurrency in Action: by Anthony Williams.
Here are the classes:
class thread_pool
{
std::atomic_bool done;
thread_safe_queue<std::function<void()> > work_queue;
std::vector<std::thread> threads;
join_threads joiner;
void worker_thread()
{
while(!done)
{
std::function<void()> task;
if(work_queue.try_pop(task))
{
task();
}
else
{
std::this_thread::yield();
}
}
}
public:
thread_pool():
done(false),joiner(threads)
{
unsigned const thread_count=std::thread::hardware_concurrency();
try
{
for(unsigned i=0;i<thread_count;++i)
{
threads.push_back(
std::thread(&thread_pool::worker_thread,this));
}
}
catch(...)
{
done=true;
throw;
}
}
~thread_pool()
{
done=true;
}
template<typename FunctionType>
void submit(FunctionType f)
{
work_queue.push(std::function<void()>(f));
}
};
template<typename T>
class threadsafe_queue
{
private:
mutable std::mutex mut;
std::queue<T> data_queue;
std::condition_variable data_cond;
public:
threadsafe_queue()
{}
void push(T new_value)
{
std::lock_guard<std::mutex> lk(mut);
data_queue.push(std::move(new_value));
data_cond.notify_one();
}
void wait_and_pop(T& value)
{
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk, [this]{return !data_queue.empty(); });
value = std::move(data_queue.front());
data_queue.pop();
}
std::shared_ptr<T> wait_and_pop()
{
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk, [this]{return !data_queue.empty(); });
std::shared_ptr<T> res(
std::make_shared<T>(std::move(data_queue.front())));
data_queue.pop();
return res;
}
bool try_pop(T& value)
{
std::lock_guard<std::mutex> lk(mut);
if (data_queue.empty())
return false;
value = std::move(data_queue.front());
data_queue.pop();
}
std::shared_ptr<T> try_pop()
{
std::lock_guard<std::mutex> lk(mut);
if (data_queue.empty())
return std::shared_ptr<T>();
std::shared_ptr<T> res(
std::make_shared<T>(std::move(data_queue.front())));
data_queue.pop();
return res;
}
bool empty() const
{
std::lock_guard<std::mutex> lk(mut);
return data_queue.empty();
}
};
The main() function:
std::condition_variable waitForThreads;
std::mutex mut;
std::atomic<unsigned> doneCount = 0;
unsigned threadCount = 4; // sample concurrent thread count that I use for testing
void synchronizeWork()
{
doneCount++;
if (doneCount.load() == threadCount)
{
doneCount = 0;
std::lock_guard<std::mutex> lock(mut);
waitForThreads.notify_one();
}
}
void Task_A()
{
std::cout << "Task A, thread id: " << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
synchronizeWork();
}
int main()
{
unsigned const thread_count = std::thread::hardware_concurrency();
thread_pool threadPool;
for (int i = 0; i < 1000; ++i)
{
for (unsigned j = 0; j < thread_count; j++)
threadPool.submit(Task_A);
// Below is my way of synchronizing the tasks
{
std::unique_lock<std::mutex> lock(mut);
waitForThreads.wait(lock);
}
}
I am not familiar with the threadpool class you are using.
Without using such a class, the usual way to do this looks like this:
std::cout << "Spawning 3 threads...\n";
std::thread t1 (pause_thread,1);
std::thread t2 (pause_thread,2);
std::thread t3 (pause_thread,3);
std::cout << "Done spawning threads. Now waiting for them to join:\n";
t1.join();
t2.join();
t3.join();
std::cout << "All threads joined!\n";
I would imagine that any decent threadpool class would allow you to the same sort of thing, even more simply, by giving you a metho to block until all the threads have completed. I suggest you double check the documentation.

Resources