On Sep 14, 2011, at 4:20 PM, Dave Zarzycki wrote:

> 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

Well, I *am* using GCD  ;)

A "Synchronous Channel" (or Synchronous Queue) is a well known pattern used in 
multithreading. Basically, it is used to "hand off" objects from one thread to 
another, with the requirement that the "producer" waits until a "consumer" took 
the object.

The synchronous queue is a blocking queue, and this blocking is used as a means 
to "throttle" the use of system resources.

In certain scenarios there is no other way to stop some code which allocates 
resources by blocking its thread. When you use dispatch queues to schedule 
"work items", these work items may contain resources. But consider, these 
resources stay allocated as long as the block waits in the dispatch queue to be 
processed by some other task and deallocates the resources again when it is 
finished. 

So, imagine this:
A producer, and consumer in action:
while (!canceled) {
   NSData * data = … create new data
   dispatch_async(process_data_queue, ^{
        [consumer processData:data];
   });
}  

If you do this, you may very probable drive your system into an insane state if 
the "producer rate" is higher than the "consumer rate". In order to fix the 
balance, you would use semaphores, and the Synchronous Channel is exactly this.


Regards
Anderas



 

> 
> 
> 
> 
> 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 protected])

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to