Re: Implementing a "Synchronous Channel" with dispatch
Re: Implementing a "Synchronous Channel" with dispatch
- Subject: Re: Implementing a "Synchronous Channel" with dispatch
- From: Dave Zarzycki <email@hidden>
- Date: Wed, 14 Sep 2011 07:20:21 -0700
Andreas,
This is probably not the answer you're looking for, but when we find coding patterns like this in the OS, we advice developers to replace this pattern with a GCD queue and use either dispatch_sync() or dispatch_async(). The reason for this advice is because parking threads to wait for events isn't an efficient use of system resources.
davez
On Sep 14, 2011, at 5:40 AM, Andreas Grosam wrote:
> Dear List,
>
> I've implemented a simple "Synchronous Channel" using dispatch lib.
> A "synchronous channel" is an actor in which each producer offering an item (via a put operation) must wait for a consumer to take this item (via a get operation), and vice versa.
>
> The following is probably the simplest implementation, which lacks some important features like timeout etc.
>
> But anyway, is the following a proper and *efficient* implementation when using dispatch lib where consumers and producers will be scheduled in queues and the semaphore is implemented using dispatch_semaphore?
>
> Any hints to improve this?
>
>
> template <typename T>
> class SimpleSynchronousChannel {
> public:
> SimpleSynchronousChannel()
> : sync_(0), send_(1), recv_(0)
> {
> }
>
> void put(const T& v) {
> send_.wait();
> value_ = v;
> recv_.signal();
> sync_.wait();
> }
>
> T get() {
> recv_.wait();
> T result = value_;
> sync_.signal();
> send_.signal();
> return result;
> }
>
> private:
> T value_;
> semaphore sync_;
> semaphore send_;
> semaphore recv_;
> };
>
>
>
> benchmark info: if I run concurrently one producer (performing put()) and one consumer (performing get()), I get a throughput of about 200.000 items/sec on a MacBookPro)
>
>
>
>
>
>
> class semaphore is a simple wrapper around dispatch_semaphore:
>
>
> class semaphore : noncopyable {
> public:
> explicit semaphore(long n) : sem_(dispatch_semaphore_create(n)) {
> assert(sem_);
> }
> ~semaphore() {
> dispatch_release(sem_);
> }
> void signal() {
> dispatch_semaphore_signal(sem_);
> }
> bool wait() { return dispatch_semaphore_wait(sem_, DISPATCH_TIME_FOREVER) == 0; }
> bool wait(double timeout_sec) {
> long result = dispatch_semaphore_wait(sem_,
> timeout_sec >= 0 ?
> dispatch_time(DISPATCH_TIME_NOW, timeout_sec*1e9)
> : DISPATCH_TIME_FOREVER);
> return result == 0;
> }
>
> private:
> dispatch_semaphore_t sem_;
> };
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden