FIFO serial queue using GCD

21,320

This is a FIFO queue in GCD:

dispatch_queue_t serialQueue = dispatch_queue_create("com.blah.queue", DISPATCH_QUEUE_SERIAL);

...
dispatch_async(serialQueue, ^{
    //block1
});

dispatch_async(serialQueue, ^{
    //block2
});
Share:
21,320
Ælex
Author by

Ælex

I'm an ML/AI researcher who sold his soul to the industry. I love working on RL, ML, CV using Python (PyTorch, Keras, TF, etc). Used to work on C++/ROS/OpenCV for Robotics. I'm not looking for a job, but I'm definitely interested in Startups.

Updated on July 14, 2022

Comments

  • Ælex
    Ælex almost 2 years

    I am trying to create a (network) synchronized array for the company I work for. While the networking part works fine, I have dwelled into an issue.

    My wish was to create a new queue using dispatch_create_queue, to which I would add two blocks that are not to run on the main thread, but in a serial manner, meaning that first the first block has to run, then the second, and never in parallel.

    I've read the apple documentation, but it is confusing to say the least.

    • When I create my queue using dispatch_queue_create and then add the blocks (after they have been defined) using dispatch_sync, I have found out that the block is still executing on the main thread.

    • When using dispatch_async, thats when the blocks are not executing on the main thread.

    • When I try to add both blocks using dispatch_sync They get blocked forever.

    • The only time that both blocks seem to run fine and off the main thread is when calling dispatch_async.

    However the reason why I chose GCD and the sync method so that I was under the impression that I was creating a new queue (and thus a new thread) and that adding blocks to that queue would simply block one until the other had finished executing. Is this not the case, or does creating a queue does not guarantee that the code will not run on the main thread ?

  • Ælex
    Ælex over 11 years
    So it has nothing to do with dispatch_sync then ? Only the flag used when creating it?
  • Fernando Mazzon
    Fernando Mazzon over 11 years
    The dispatch_async makes it so that the dispatch call itself doesn't block until the block is finished. If you use dispatch_sync, the task itself is executed in whatever thread the queue is in, but you block the current thread until the task is done. I don't think that's what you need.
  • Ælex
    Ælex over 11 years
    Thank you, those api names are a bit confusing. Saved my day ! :)
  • jscs
    jscs over 11 years
    @Joe: dispatch_async() doesn't really mean "run in the background", it just means "don't wait for this to run". (There's also no guarantees made by GCD for thread/queue correspondance other than that the main queue is on the main thread.)
  • jmstone617
    jmstone617 over 11 years
    All dispatch queues are FIFO. Meaning that as long as you reuse the same queue, the order of block execution is determined and guaranteed not to lock and is thus thread-safe.
  • gnasher729
    gnasher729 about 9 years
    @jmstone: You mean all serial dispatch queues are FIFO. For concurrent queues, you should assume that all blocks are executing in parallel.
  • jmstone617
    jmstone617 about 9 years
    @gnasher729 Even concurrent queues are technically FIFO. From Apple's documentation on concurrent queues: "Concurrent queues (also known as a type of global dispatch queue) execute one or more tasks concurrently, but tasks are still started in the order in which they were added to the queue."
  • PruitIgoe
    PruitIgoe almost 8 years
    @jmstone Wouldn't a concurrent queue be first in only? Since they are running in parallel you have no guarantee that the first job in will be the first job out? I've experienced this with making calls to Google's GeoCode API, where I've sent a series of queries that were stored in an array (addresses) and the returned JSON does not come back in the same order that I sent. I.E. Send Address1, Address2, Address3 in that order and the location data returned could be Location 2, Location 1, Location 3...
  • jmstone617
    jmstone617 almost 8 years
    @PruitIgoe FIFO does not mean FIFC (first in first to complete). Like I mentioned above, the FIFO order just guarantees that tasks are started in the order they were added to the queue. That doesn't mean they FINISH in the same order, as evidenced by the example you gave.
  • iDevAmit
    iDevAmit almost 7 years
    What if I have dynamic count of tasks, can I use for loop for execution?
  • Isaaс Weisberg
    Isaaс Weisberg about 5 years
    @jmstone617 oh god dammit, I had a case in which a seemingly serial queue was somehow allowing for multiple concurrency despite the flags I set. Went here and then read your comment to this answer talking about how important it is to ACTUALLY use the same DispatchQueue object to push work items into async. AKA 2 DispatchQueues with same labels are not equal. Thank you for your brief tip
  • Conor
    Conor over 2 years
    FIFO stands for First In First Out. "First in" refers to first queued, "first out" refers to first out of the queue and to begin execution. What happens after that is no longer the queues domain. Hence the question demands for a serial queue, that will not start execution of the second task, until the first one is done.