need examples of a proper way to wait for a flag change in another thread without blocking the events?. In C++/windows.
Printable View
need examples of a proper way to wait for a flag change in another thread without blocking the events?. In C++/windows.
how about condition variables versus events?. Both work at kernel level?. Which is more proper to use?.
What " condition variables" do you mean?
This is what I mean?. Condition variables versus events.. ?
https://en.cppreference.com/w/cpp/th...ition_variable
Well, both "condition variables" that you meant (std::mutex) and MS Event Objects (Synchronization) are synchronization objects. So I do not see any difference.
However, I never used std::threads, so that is only my IMHO and I may be wrong.
Sorry, but I don't use std::threads either.
why you do not use std::threads?. What are other alternatives based on your experiences?. Specially for passing array of objects to it in C++. I read _beginthread(ex) are appropriate for C++.
Because std::threads did NOT exist when we had begonnen using multithreading in MS Windows applications.
We had _beginthread(ex)/_endthread(ex) to use in a plain c++/Win32 applications and a little more convenient AfxBeginThread for MFC.
So why should we change/rewrite our good working since the decade code? :confused:
plus Windows events, mutexs, semaphores etc etc etc
We only use Windows and our main threading code was written before C++11. We looked into moving to std::threads etc but we concluded that the cost of converting far outweighed any benefit to us.
I often use a thread-safe producer-consumer queue for this kind of situation. The producer thread pushes information on the queue and the consumer thread pops it, either by active polling or waiting asleep.
This is my code (inspired by the very good book "C++ Concurrency in Action" by Anthony Williams, 2 edition, page 179)
To use Lockqueue, the producer allocates a Lockqueue object on the heap using new. This pointer preferably (but not necessarily) is kept in a smart pointer called std::shared_ptr to ensure a safe automatic delete. It is thread-safe,Code:#ifndef LOCK_QUEUE_ONCE
#define LOCK_QUEUE_ONCE
//
// Threadsafe queue
//
#include <queue>
#include <memory>
#include <condition_variable>
#include <mutex>
namespace maux {
template<typename T>
class Lockqueue {
using Mutex = std::mutex;
public:
void push(T value) { // push
const std::lock_guard<Mutex> lock(mutex);
queue.push(std::move(value));
condition.notify_one();
}
bool try_pop(T& value) { // poll pop
std::lock_guard<Mutex> lock(mutex);
if (queue.empty()) return false;
value = std::move(queue.front());
queue.pop();
return true;
}
T wait_pop() { // wait pop
std::unique_lock<Mutex> lock(mutex);
condition.wait(lock, [this] () noexcept {return !queue.empty();});
T const value = std::move(queue.front());
queue.pop();
return value;
}
int size() const { // queue size
std::lock_guard<Mutex> lock(mutex);
return static_cast<int>(queue.size());
}
private:
mutable Mutex mutex;
std::queue<T> queue;
std::condition_variable condition;
};
}
#endif
https://docs.microsoft.com/en-us/cpp...?view=msvc-160
Then the producer passes the (smart) pointer over to the consumer when it is started.
Note that most algorithms of the C++ standard library can run in parallel today. It is no longer necessary to always manage own threads to achieve that.