On Sep 14, 2011, at 7:18 PM, Kyle Sluder wrote: > On Wed, Sep 14, 2011 at 9:38 AM, Andreas Grosam <agro...@onlinehome.de> wrote: >> 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. > > If you want to block the producer until its object is consumed, why > not use dispatch_sync? > > void producer() { > while (1) { > dispatch_sync(consumer_queue, ^{ > dispatch_async(consumer_queue, ^{ > // consume the thing > } > } > } > } > > --Kyle Sluder
Hm, if we dispatch "consume the thing" asynchronously, wouldn't it return pretty fast? It would also not wait until consumer has processed the data in "consume the thing"? So, possibly many data objects can be created by the producer, then waiting in a dispatch queue without having a means to throttle this? Also, I could possibly schedule several "consume the thing" work items - but what if "consume the thing" is only *one* operation, and cannot be performed by several sequential operations? In fact, my consumer cannot partially consume content provided by one NSData object, then return with result "STILL_HUNGRY", and then restart with the next partial data. Instead, the running consumer can be fed with NSData objects from a producer thread at any point in time. This, however should block if consumer is still chewing on the previous mouthful. Here is the problem as brief as I can present it: "consumer" will do roughly the following: // Start a worker thread on the global concurrent queue. // start will be invoked by some Controller object, which also listens to notifications (async blocks), sent // from consumer while it processes the data: - (void) start { dispatch_async(dispatch_get_global_queue(),^{[self run]}); } // run is the actual task of the consumer - only after when it is finished // with one or more NSData objects, it returns. // runs in its own thread! - (void) run { char ch; while (!done && (ch = [self next]) != 0) { // invokes nested methods, each can invoke next } } // retrieve the next char from the buffer. If we are finished with the buffer, // get a new buffer. This may block. - (char) next { if (p_ == buffer_end_) { buffer_ = [synchronousQueue_ getData]; // blocks until data is offered p_ = [buffer_ bytes]; buffer_end_ = p_ + [buffer length]; } char ch = *p_++; return ch; } // Here we feed the consumer with the next data buffer: - (void) consumeTheThing:(NSData*)thing { [synchronousQueue_ putData:thing]; } So for example, a NSURLConnection is the producer: - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { // we are not on the main thread! [consumer_ consumeTheThing:data]; // blocks until data has been taken (this will throttle download) } Andreas _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) 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 arch...@mail-archive.com