How I Learned to Stop Worrying and Handle Concurrency.
Concurrency is an unavoidable subject when creating a GUI application. In particular, heavy processes such as network communication and file I/O are generally handled by a separate thread from the GUI thread. Such threads are created in two ways:
- The application explicitly creates threads.
- The application implicitly creates threads via an API and asynchronously receives results with a callback function.
(We’ve heard that it’s under development for Chrome though, and we’re eagerly awaiting for support by other browser vendors as well!)
Case 1: Asynchronous Calls
Let’s first consider a simple asynchronous call.
Grand Central Dispatch (GCD), a framework for handling the queue, is most frequently used on iOS for asynchronous processes. GCD is implemented in the libdispatch library. But since it uses pthread and the iOS kernel API, it can’t be used as is.
Case 2: Explicit Calls
Next, let’s consider explicit calls.
Is it not possible to convert code that explicitly creates new threads? Have no fear! When we looked at the source code of several iOS applications, we found that most explicitly created threads fell into one of these three categories.
- When the task is completed, it terminates as is without notifying the result to other threads.
- When the task is completed, it notifies the main thread with a callback.
- It repeats some process using NSRunLoop (process some sort of task queue).
In each of these cases, NSThread is typically used.
So we reimplemented NSThread using GCD. Now, as long as these threads are called in an orderly fashion using NSThread, they are automatically processed using the queue without any code modifications.
This does mean that processes that would have been handled in the background are now executed in the main thread (postponed by setTimeout()), so there are times when the app lags a bit.
We can now support iOS concurrency in our converted web applications. But we’re looking forward to the day when we can throw out all this code and use pthreads instead!