Race conditions, threads, processes, tasks, queues in iOS

What is a race condition?

When you have two threads changing a variable simultaneously. It’s possible to get unexpected results. Imagine a bank account where one thread is subtracting a value to the total and the other is adding a value.

The order of events goes like this:

  1. Access the total to subtract to it. (total = 500, expense = 40)
  2. Compute the difference. (total =500, newTotal = 460)
  3. Save the new total. (total = 460)
  4. Access the total to add to it. (total = 460, income = 200)
  5. Compute the sum (total = 460, newTotal = 660)
  6. Save the new total (total = 660)

Great! 660 is exactly what we expected, but it could have gone like this:

  1. Access the total to subtract to it. (total = 500, expense = 40)
  2. Access the total to add to it. (total = 500, income = 200)
  3. Compute the difference. (total =500, newTotal = 460)
  4. Save the new total. (total = 460)
  5. Compute the sum (total = 500, newTotal = 700)
  6. Save the new total. (total = 700)

So the account is now at 700. That’s not what we expected. Uh oh.

When should we suspect a race condition?

When variables that have multiple threads operating on them and you’re getting unexpected results some of the time.

How do we fix this?

One option is to lock the variable total so that only one thread could operate on it at a time, the lock is called a mutex.

But in iOS, you want to use grand central dispatch (GCD) or OperationQueues to handle your tasks. So in the example of the bank total, we’d probably just want to use a serial dispatch queue which has sole access to the total variable. By using GCD or OperationQueues, you’re letting Apple do the thread management and removing the code for locking. Less code is good.

So what are threads, processes and tasks?

The task is an abstract concept for describing something you want to do. In the example above, adding money to the total or subtracting money from the total are both tasks. They use a process to actually affect the change in code.

A process keeps track of what needs to be done and delegates the tasks to the threads. A process can have one or multiple threads. The process is like a project manager and the thread is like a worker.

What’s the difference between hardware and software threads?

The threads we’ve been talking about so far have been software threads. They’re (generally) independent units of computation.

The hardware threads are based on the number of cores on the computer. For example, the current 12 inch MacBook has this processor with a 1.1GHz two-core processor. That means it have 2 cores, each with 1.1GHz of clock speed. Each of those core have two 2 hardware threads, so there are 4 hardware threads total.

Each of these hardware threads can run many software threads, depending on how the operating system uses them.

A Curriculum of Guides about Blocks in Objective-C

Recently, there was a question about blocks that I couldn’t answer so I took a note to review it.

I came upon some great articles. Seeing the same elephant described by different people invariably leads to a comprehensive understanding of the elephant (much in the same way that taking beginner swing dance classes from 4-5 people leads to better fundamentals).

With no desire to write an inferior blog post, I’m going to review the ones I found, much the same way that I review restaurants.

The Guides

Mike Nachbaur: Using GCD and Blocks Effectively

Tutsplus: Objective-C Succinctly: Blocks

AppCoda: Introduction to Objective-C Blocks

Apple Working with Blocks

Matt Nunogawa Objective C Blocks: Summary, Syntax & Best Practices

Conrad Stoll Blocks, Operations, and Retain Cycles

I’ll be looking at:

  • explanation of why it’s important
  • completeness vs depth
  • the example code
  • ease of transferring examples to projects
  • how beginner friendly it is

Which should I read first?

Starting from Square One

Go with Tutsplus: Objective-C Succinctly: Blocks. It’s short, has useful examples and memory is well explained with diagrams. It stops short of retain loops though, which is a vital topic. Also lacking is why blocks are used (when would I want to use a block? what would I have used otherwise?).

AppCoda (Introduction to Objective-C Blocks) is really known for their app tutorials. They explain very well why you would use blocks and lead you through an example of how it would be used in a practical situation with an actual app.

Mike Nachbaur: Using GCD and Blocks Effectively extends deeper into asynchronous callbacks, introduces Grand Central Dispatch, and the idea that retain cycles can happen.

For Programmers from Other Languages

Matt Nunogawa (Objective C Blocks: Summary, Syntax & Best Practices) writes his blog directed at programmers from other languages and overviews blocks with greater examples for retain cycles and how to avoid them.

Bonus: Conrad Stoll (Blocks, Operations, and Retain Cycles) writes about a real example of a bug that his team faced with retain cycles and blocks.

For Quick Reference After Learning It Once

Apple Working with Blocks documentation can be a bit dry and doesn’t give much guidance for when to use it, but if that doesn’t bother you, then by all means go ahead. It’s very comprehensive.