Boost logo

Boost :

Subject: Re: [boost] Request for interest in the new Synchro library
From: Dmitry Goncharov (dgoncharov_at_[hidden])
Date: 2009-03-04 04:06:32


vicente.botet wrote:
>> What about the following adapter?
>>
>>
>> #ifndef BOOST_BINSEM_HPP
>> #define BOOST_BINSEM_HPP
>>
>> #include <boost/thread.hpp>
>>
>> namespace boost
>> {
>> template <typename Semaphore>
>> class binary_semaphore
>> {
>> public:
>> explicit binary_semaphore(int v)
>> : m_sem(v)
>> {}
>>
>> void wait()
>> {
>> m_sem.wait();
>> }
>>
>> void post()
>> {
>> // If cannot lock then some other thread is posting.
>> // In this case just return.
>> if (m_mutex.try_lock())
>> {
>> try
>> {
>> // The result of try_wait() is not important.
>> m_sem.try_wait();
>> m_sem.post();
>> }
>> catch (...)
>> {
>> m_mutex.unlock();
>> throw;
>> }
>> m_mutex.unlock();
>> }
>> }
>>
>> bool timed_wait(boost::posix_time::ptime const& t)
>> {
>> return m_sem.timed_wait(t);
>> }
>>
>> bool try_wait()
>> {
>> return m_sem.try_wait();
>> }
>>
>> private:
>> boost::mutex m_mutex;
>> Semaphore m_sem;
>> };
>> }
>>
>> #endif
>>
>> This adapter makes a binary semaphore out of a regular one. The post()
>> method is not as efficient as it should be. On the other hand the
>> adapter is very simple.
>> There is also a test attached.
>>
>
> Thanks for the proposal. I have another alternative using inheritance that avoid adding a new mutex.
>
> template <typename ScopeTag=multi_threaded_tag>
> class basic_binary_semaphore: public basic_semaphore<ScopeTag> {
> public:
> BOOST_COPY_CONSTRUCTOR_DELETE(basic_binary_semaphore) /*< disable copy construction >*/
> BOOST_COPY_ASSIGNEMENT_DELETE(basic_binary_semaphore) /*< disable copy asignement >*/
>
> inline explict basic_binary_semaphore(int initialCount):basic_semaphore<ScopeTag>(initialCount>0?1:0) {};
>
> inline void post()
> {
> scoped_lock lock(this->m_mut);
> if(this->m_count == 0){
> this->m_cond.notify_one();
> ++(this->m_count);
> }
> }
> };
> typedef basic_binary_semaphore<> binary_semaphore;
>
> Attached the complete file. What do you think?
>
> Thanks,
> Vicente
>
>
Could not find basic_semaphore in boost. Is it one from your Synchro
library?

Locking a mutex inside post() is inefficient. If one thread has the
mutex locked then there is no need to wait until the mutex is unlocked.
Use try_lock() and return if cannot lock.

In one of the previous posts i described why a
binary_semaphore::timed_wait() was superior in my case than
condition_variable::timed_wait(). Using a condition variable defeats the
purpose of a binary_semaphore (at least in my usage scenario).

BR, Dmitry


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk