简体   繁体   中英

Sharing a queue between a thread and another polling thread

I'm writing an iOS application in which multiple iDevices can connect to each other and send messages to each other. When iDevice1 sends a message to iDevice2, I want that message to be inserted into a queue in iDevice2. A separate background thread on iDevice2 now goes through this queue and dequeues the messages. My question is two fold and is as follows:

  1. What is the best way to implement a background thread that loops indefinitely (until the app is terminated) and polls and dequeues items from a queue?
  2. What is the best way to share the queue between the looping background thread and the thread that inserts messages into the queue?

I have been using the dispatch_async grand central dispatch approach to perform tasks in different threads and it's been working very well. Should I use the dispatch_async method in order to start off my background thread that polls the queue? Does this approach take care of switching to other threads or will the background thread hog the processor since it's doing an indefinite loop? Any help is appreciated, thanks!

The more important / interesting question here is why you have a background thread (polling or otherwise) feeding into a GCD queue vs simply making the whole thing a GCD based workflow with blocks running on one queue (which might be associated with a dispatch source or semaphore) submitting work into the work queue. In other words, the code managing iDevice1 and iDevice2 both should be written using GCD and expressing the intention of the workflow vs having any manual thread management going on. The code will be easier to understand and more maintainable!

You don't want to poll, that's bad practice, it uses CPU for no good reason. What you want to do is setup a shared fifo using ie a NSMutableArray and protect its access with a NSConditionLock. The consumer task (that you can create with a NSOperation) will lock on the NSConditionLock until the producer task signals that there is some data available in the fifo.

There's no need to poll the queue--items on the queue will execute according to the queue's semantics. You could do something like this:

-(dispatch_queue_t)messageQueue {
    static dispatch_queue_t queue;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        queue = dispatch_queue_create("my message queue", DISPATCH_QUEUE_SERIAL);
    });
    return queue;
}

-(void)didRecieveMessage:(NSString *)message {
    dispatch_async([self messageQueue], ^{
        // do something with message
        dispatch_async(dispatch_get_main_queue(), ^{
            // update the UI
        });

    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM