A program is said to be single-threaded if it executes one instruction/sequence at a time. The single-threaded programs follow the “serial execution method” or “sequential execution approach.” All the instructions are executed by a single thread called the main thread.
In single-threaded programs, there is no concept of concurrent execution or parallelism. These programs are easy to reason with and simple as the instructions are executed sequentially.
Asynchronous means a program can work or execute another sequence of instructions while one of the sequences waits. It is responsive and lets the other instructions manage instead of making them starve. There are different approaches to creating a program asynchronous, like using callbacks, promises, or routines.
An important thing to notice is that asynchronous doesn't mean multi-threaded programming.
An important thing to notice is that asynchronous doesn't mean multi-threaded programming.
Before diving into how a single-threaded program can be made asynchronous, we must clearly understand how asynchronous programming differs from synchronous programming.
Asynchronous Programming | Synchronous Programming |
Tasks are executed cocurrently and independently | Tasks are executed one after another in a sequential manner |
Tasks can start, pause, and resume their execution without waiting for other tasks to complete | Each task must complete before the program moves on to the next task |
Code can be more complex to write and reason about due to the asynchronous nature of task execution. | Typically easier to reason about as the flow of execution is straightforward and follows a predictable order |
Event-driven programming: A single-threaded program can be made asynchronously using event handlers and trigger events. An asynchronous task is initiated, and the program executes the rest of the instructions while the asynchronous task is completed. As soon as this asynchronous task is finished, it will trigger an event handled by the handler. This allows the execution of multiple sequence instructions without waiting for one or blocking the rest.
Coroutine-based programming: Coroutines are supported by some programming frameworks, including Python. They offer a more synchronous style of execution, allowing routines to be paused and resumed without blocking other instructions.
The asyncio
module is a framework for writing asynchronous code using coroutines, tasks, and event loops. The provided code is an example of asyncio based code in Python.
import asyncioasync def asynchronous_task(name, delay):print(f'Starting {name}')await asyncio.sleep(delay)print(f'Finished {name}')@asyncio.coroutinedef main():print('Main program started')# Create and schedule multiple asynchronous taskstask1 = asyncio.ensure_future(asynchronous_task('Task 1', 2))task2 = asyncio.ensure_future(asynchronous_task('Task 2', 1))# Continue executing other tasks while waiting for the asynchronous tasks to completeprint('Continuing with other tasks')# Wait for the completion of all tasksyield from asyncio.gather(task1, task2)print('Main program finished')# Create an event loop and run the main functionloop = asyncio.get_event_loop()loop.run_until_complete(main())loop.close()
Line 3–6: The asynchronous_task
function represents an asynchronous operation that performs some work for a given duration specified by the delay
parameter. The main
function serves as the entry point for the program.
Line 9–22: Within the main
function, there are two tasks (task1
and task2
) which are created using the asyncio.create_task
function. These tasks are scheduled to run concurrently. After creating the tasks, the program executes other tasks or operations without waiting for the asynchronous tasks to complete.
Line 20: The program then used asyncio.gather
to wait to complete all tasks. The await
keyword is used to wait for the call's completion, which ensures that the program does not proceed further until both tasks have finished.
When you run this code, you'll see that the tasks start executing without waiting for each other to finish. The program continues executing other tasks, and once all the jobs are complete, the "Main program finished" message is printed.
A single-threaded program can be asynchronous. Being asynchronous does not mean it is multi-threaded. It is still a single-threaded program, allowing multiple instructions to execute concurrently without waiting for the previous ones to complete.
Free Resources