What is Concurrency? — A Simple Concurrent App

Aniello Ambrosio
7 min readApr 6, 2022

--

By Aniello Ambrosio, Antonio Iacono

Abstract

In this article we will discuss about basic concept of concurrency. Concurrency can be applied in different way to increase the performance of an app. Of course can be applied with different kind of software architecture. In our case we have applied concurrency to server client system. The server side is already done in a previous project, you can find the link at the end to see how develop it. Instead in this project we will discuss about concurrency in general and the problem’s related and how take advantage from concurrency to increase the performance of our client app to faster download data from the server.

Differences between Sequential, parallel and concurrent programming

Before we talk about Concurrency, let’s understand what it means and what is the difference with sequential and parallel. Concurrency originates from medieval Latin “concurrentia” or even from the legal Latin “concurrĕre” that means “compete for the same thing”.

To understand the difference between Concurrency, Parallel and Sequential look at an example: Imagine processes that require to be performed by the processor as people lined up in public toilets:

Imagine now to be in a civilized country, each person respects his or her place in line, in this case people will access public toilets respecting their place in the queue so you will have a queue for each available bath. In case there is only one WC there will be one person at a time to use the services, this is like a sequential programming in which there is only one processor, the processes will be executed one at a time following the queue order. In case the WCs are two or more there will be more than one person at a time to use the services, this is like a parallel programming in which there is more than one processor, the processes will be scheduled in parallel following the queues. Imagine now being in a place of rude people who do not respect each other. All push each other to enter the bathroom first, fortunately the processes are not so rude like these people but still respect queues. In Concurrent Programming more queues of processes that try to be executed by the same processor will form.

What is Concurrency?

We have already seen the differences between concurrent, parallel and sequential programming.
It should be clear the power of concurrent programming. It allows to run different task at same time in overlapping periods of time. It works with one processor but differently from sequential programming, it allows to run multiple tasks. So it is more powerful than sequential programming but is also more powerful of parallel programming which works only with multiple processors.
To handle this coding way in swift, we have can start talking about thread and queue. A program is the description of an algorithm. An instance or execution of a program is (usually at least 1) a process. So we can have different process of the same program (think about different tab in safari) but this is handled from the operating system.
Inside a process we can have some operation that could work in an asynchronous way. Here we have threads, the atomic part of our program that can be executed in concurrency with other threads inside of the same process. Think about Instagram which at same time provides us a view of different post and at same time in background continue to upload the latest post or private messages. We can imagine a program in that way:

In swift we can create this behaviour in two different ways: Task or Queue. With Task we can create a single task and we have to be careful to handle it to avoid some problems about concurrency that we will discuss later.
With Queue we can delegate this synchronization to different queue of tasks inside our program. We can have different queue with different priority and we can also create custom queue. Just to make an example, the task in charge of the handling of the views should have an higher priority than a task in charge of the downloading data from a server/database.

Problems about concurrency

As we said , concurrency is powerful but there are a lot of issue that we have to consider when we use it. We can focus on 4 category of problem:

Race Condition: It occurs when 2 or more tasks/thread needs the same resources. In this case we have to provide a synchronization between the tasks.

© All rights of the original picture are reserved to Marvel

Deadlock: in this case we have 2 (or more tasks) A and B. A is using the resource X and B is using the resource Y. To finish the execution A needs Y but Y is locked from B. But at same, to finish the execution B needs X which is locked from A. In this case neither A and B can finish their task. Also in this case we need to synchronize A and B. For example if A has the highest priority, we could unlock Y from B to allow A to terminate

Priority Inversion:it occurs when a task with high priority is executed after other task with lower priority. It’s like when you are driving a car and at a semaphore you see the green light but cars with the red and yellow light pass before you.

Credits: Maxim Abramov, https://unsplash.com/photos/GFjyimhomaM

Starvation: it occurs when a task with low priority can’t be executed because there are other task with higher priority.

Project Overview

Our project is a simple way to test the power of the concurrency. We have structured it with the MVVM model. In the file APIService.swift we implemented the interface to make request to a server to get data. We also included a photo.jsonfile in case the service is off. In PhotoListViewModel.swift we fetch new data to update the PhotoListView.swift

Where and how we used concurrency

Concurrency can be used for a lot of things. We used it in the easiest and maybe the most used way: get data in parallel to increase the performance and the speed of our app. In PhotoListViewModel.swift we used async/await to make get many data at same time.

//PhotoListViewModel.swift
@MainActor
func fetchPlanet() async {
let apiService = APIService(urlString: "<http://127.0.0.1:8080/>")
isLoading.toggle()
defer {
isLoading.toggle()
}
do {
planet = try await apiService.getJSON()
} catch {
showAlert = true
errorMessage = error.localizedDescription + "\\nPlease contact the developer and provide this error and the steps to reproduce."
}
}
//PhotoListView.swift
.task {
await vm.fetchPhoto()
}

In this few lines of code there are a lot of work behind. We can focus on some keywords: @MainActor, task, async and await.

async: when we declared the function fetchPlanet() we used the keyword async because in this way we can start the fetching of the data and we can continue to execute other tasks at the same time.

await: when we did planet = try await apiService.getJSON() with await we are just waiting that the data request is done in order to catch some error only when the request is finished.

task: we can create an asynchronous task to perform when this view (PhotoListView()) appears.

@MainActor: We are specifying that the fetchPlanet() should be handled from the main queue.In swift each project execute at least 1 task. When there are more than 1 task we can handle them in different way. Or task by task or with the queue.With @MainActor we can run our code on the main queue. For example, the views updates should be executed on the main queue, instead other task can be executed on the background queue.

defer: with this keyword you can run code when the current scope exists. It’s used when you are ending a task, because it’s finished or because of an error, to clean up and set up all the condition or variable for the next execution.

Server Integration

In the final steps we have connected this client app with a previous server app we already created. The server app use a local IP so it will be visible only from your same mac so you can test the client app only from simulator.
The first think to do is publish the server, so you need to run the server app and then you can start the client app and see that in the main view there are effectively the downloaded photo from the server.
Than using tool like Insomnia or PostMan you can put a new element inside the Database that it will be shown by refreshing the app page.

Wrap-up

We have seen what is concurrency, we understood how handle it in swift to avoid the main issues. If you are interested in reading more about our code, just click below on GitHub links of source code.

> A simple planets app — Concurrency and Json APIservice
> A simple planets app — Server Integration

If you are interested in reading about our Server Side article and project, please visit the page below.

--

--