user965972
user965972

Reputation: 2587

priority control with semaphore

Suppose I have a semaphore to control access to a dispatch_queue_t. I wait for the semaphore (dispatch_semaphore_wait) before scheduling a block on the dispatch queue.

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER)
dispatch_async(queue){ //do work ; dispatch_semaphore_signal(semaphore); }

Suppose I have work waiting in several separate locations. Some "work" have higher priority than the other "work".

Is there a way to control which of the "work" will be scheduled next?

Additional information: using a serial queue without a semaphore is not an option for me because the "work" consist of its own queue with several blocks. All of the work queue has to run, or none of it. No work queues can run simultaneously. I have all of this working fine, except for the priority control.

Edit: (in response to Jeremy, moved from comments)

Ok, suppose you have a device/file/whatever like a printer. A print job consists of multiple function calls/blocks (print header, then print figure, then print text,...) grouped together in a transaction. Put these blocks on a serial queue. One queue per transaction.

However you can have multiple print jobs/transactions. Blocks from different print jobs/transactions can not be mixed. So how do you ensure that a transaction queue runs all of its jobs and that a transaction queue is not started before another queue has finished? (I am not printing, just using this as an example).

Semaphores are used to regulate the use of finite resources. https://www.mikeash.com/pyblog/friday-qa-2009-09-25-gcd-practicum.html Concurrency Programming Guide

The next step I am trying to figure out is how to run one transaction before another.

Upvotes: 2

Views: 1194

Answers (1)

Jeremy Huddleston Sequoia
Jeremy Huddleston Sequoia

Reputation: 23623

You are misusing the API here. You should not be using semaphores to control what gets scheduled to dispatch queues.

If you want to serialize execution of blocks on the queue, then use a serial queue rather than a concurrent queue.

If different blocks that you are enqueuing have different priority, then you should express that different priority using the QOS mechanisms added in OS X 10.10 and iOS 8.0. If you need to run on older systems, then you can use the different priority global concurrent queues for appropriate work. Beyond that, there isn't much control on older systems.

Furthermore, semaphores inherently work against priority inheritance since there is no way for the system to determine who will signal the semaphore and thus you can easily end up in a situation where a higher priority thread will be blocked for a long time waiting for a lower priority thread to signal the semaphore. This is called priority inversion.

Upvotes: 2

Related Questions