Is it true that C++0x will come without semaphores? There are already some questions on Stack Overflow regarding the use of semaphores. I use them (posix semaphores) all the
I decided to write the most robust/generic C++11 semaphore I could, in the style of the standard as much as I could (note using semaphore = ...
, you normally would just use the name semaphore
similar to normally using string
not basic_string
):
template
class basic_semaphore {
public:
using native_handle_type = typename CondVar::native_handle_type;
explicit basic_semaphore(size_t count = 0);
basic_semaphore(const basic_semaphore&) = delete;
basic_semaphore(basic_semaphore&&) = delete;
basic_semaphore& operator=(const basic_semaphore&) = delete;
basic_semaphore& operator=(basic_semaphore&&) = delete;
void notify();
void wait();
bool try_wait();
template
bool wait_for(const std::chrono::duration& d);
template
bool wait_until(const std::chrono::time_point& t);
native_handle_type native_handle();
private:
Mutex mMutex;
CondVar mCv;
size_t mCount;
};
using semaphore = basic_semaphore;
template
basic_semaphore::basic_semaphore(size_t count)
: mCount{count}
{}
template
void basic_semaphore::notify() {
std::lock_guard lock{mMutex};
++mCount;
mCv.notify_one();
}
template
void basic_semaphore::wait() {
std::unique_lock lock{mMutex};
mCv.wait(lock, [&]{ return mCount > 0; });
--mCount;
}
template
bool basic_semaphore::try_wait() {
std::lock_guard lock{mMutex};
if (mCount > 0) {
--mCount;
return true;
}
return false;
}
template
template
bool basic_semaphore::wait_for(const std::chrono::duration& d) {
std::unique_lock lock{mMutex};
auto finished = mCv.wait_for(lock, d, [&]{ return mCount > 0; });
if (finished)
--mCount;
return finished;
}
template
template
bool basic_semaphore::wait_until(const std::chrono::time_point& t) {
std::unique_lock lock{mMutex};
auto finished = mCv.wait_until(lock, t, [&]{ return mCount > 0; });
if (finished)
--mCount;
return finished;
}
template
typename basic_semaphore::native_handle_type basic_semaphore::native_handle() {
return mCv.native_handle();
}