Can I limit concurrent requests using GCD?

荒凉一梦 提交于 2019-11-29 07:12:51

Something like this:

...
//only make one of these obviously :) remaking it each time you dispatch_async wouldn't limit anything
dispatch_semaphore_t concurrencyLimitingSemaphore = dispatch_semaphore_create(limit);
...
//do this part once per task, for example in a loop
dispatch_semaphore_wait(concurrencyLimitingSemaphore, DISPATCH_TIME_FOREVER);
dispatch_async(someConcurrentQueue, ^{
    /* work goes here */
    dispatch_semaphore_signal(concurrencyLimitingSemaphore);
}

I suggest this solution for limited concurrent execution of synchronous tasks:

func dispatch_async_batch(tasks: [() -> ()], limit: Int, completion: (() -> ())?) {
    if tasks.count > 0 || completion != nil {
        let q = dispatch_queue_create("dispatch_async_batch", DISPATCH_QUEUE_CONCURRENT);
        let sema = dispatch_semaphore_create(limit);

        dispatch_async(q, {
            for task in tasks {
                dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
                dispatch_async(q, {
                    task()
                    dispatch_semaphore_signal(sema)
                })
            }

            if let completion = completion {
                dispatch_barrier_async(q, completion)
            }
        })
    }
}

This approach has small overhead: only one extra task is put on the queue (i.e. one extra thread) aside the currently executing ones. It's especially good when you have big overall amount of tasks.

This gist is a ready to use demo, just put the code into a playground.

The easy way is to set up n serial queues

struct dataCalls {
    let n:Int
    func fetchIt(){
        print ("Done",n)
    }

    init(n:Int){
        self.n=n
    }
}

var dataCallsArray: [dataCalls]=[]
var qArray:[dispatch_queue_t] = []
let n = 5
for i in 1...50 {
    dataCallsArray.append(dataCalls(n:i))
}

for _ in 1...n {
    qArray.append(dispatch_queue_create(nil, nil))
}

var i = 0
for data in dataCallsArray {
    dispatch_async(qArray[i%n], {() -> Void in data.fetchIt()})
    i++
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!