Attempting to run two processes simultaneously in GCD
I'm attempting to load two sets of data in the background simultaneously through GCD in iOS. Currently, I built two distinct concurrent queues, in which I run each of the tasks. However, the delay between the completion of the first queue and the second queue (which run identically intensive tasks) is very large (so I assume that they are not running concurrently). Do you guys have any suggestions about how to fix this? I don't completely understand the correct way to approach this. Thanks!
dispatch_queue_t myQueue = dispatch_queue_create("com.a.identifier", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t myQueue2 = dispatch_queue_create("com.a.identifier2", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myQueue, ^{
[self fetchDataWithDataFromUrl:[NSURL URLWithString:linkOne]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
});
dispatch_async(myQueue2, ^{
[self fetchDataWithDataFromUrl2:[NSURL URLWithString:linkTwo]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
});
They are very likely running concurrently. They may not be running in parallel. It's important to know the difference. GCD provides concurrency, it makes few promises about parallelism. This is true of many libraries (and is usually the more important feature).
How many cores do you have? If you only have a single core, then it is not surprising if the second job waits for the first to complete. If you have two cores, but the main queue has a lot of work on it, then it's likely to get prioritized before one of your blocks. You should use the GCD tools in Instruments to explore when things are getting scheduled ( printf
is also a powerful tool here). Remember, context switching costs time. To get the best throughput on a core, you want to run one thing on it until that thing is complete, then run the next thing. Switching back and forth to get them to complete together will make both of them run more slowly. Most systems bias towards throughput. There's no reason to swap out a block in order to run a block of the same priority.
Do you know that both jobs get their data at the same time? If you're pulling from the network, it is very possible that one is coming much sooner or faster than the other. You may be pipelining on a single connection, which could serialize your network traffic. You should log when the data gets to you. You should also log when your block actually starts (put a printf()
at the top of the block).
If you need the first job to wait for the second to complete before updating the UI, then you should put both jobs into a dispatch_group so that the reloadData
waits for them.
You really need to dig into what is running and when. This kind of symptom can sometimes mean that you're updating your UI on a background thread somewhere else. That can lead to long delays in getting a correct update (possibly having nothing to do with this code). Putting in printf()
statements and using Instruments are important to make sure you know what's actually going on.
You may want to break your job up into smaller pieces and interleave them if pacing is more important than throughput (which you're suggesting it is).
链接地址: http://www.djcxy.com/p/79400.html上一篇: Prolog如何并发?
下一篇: 试图在GCD中同时运行两个进程