Multitasking is the general term for managing multiple tasks in a simulation or in solving a problem.
When it comes to implementation, there are two kinds:
Coroutines are a form of cooperative multitasking. They allow multiple entry points for suspending and resuming execution at certain points.
In many programming languages, coroutines are implemented using constructs like yield or await, which allow a function to pause its execution and return control to the caller, while maintaining its state for later resumption.
def coroutine_example(): print("Coroutine started") value = yield # Yield control back to the caller print(f"Received value: {value}") yield # Yield again, allowing further interaction print("Coroutine finished") coro = coroutine_example() next(coro) # Start the coroutine coro.send(42) # Send a value to the coroutine next(coro) # Resume the coroutine
nextSquare = coroutine.create(function () for value = 1, 5 do coroutine.yield(value * value) end return "Thank you" end) for i = 1, 8 do local status = coroutine.status(nextSquare) local success, values = coroutine.resume(nextSquare) print(status, success, values) end
nextSquare = coroutine.wrap(function () for value = 1, 5 do coroutine.yield(value * value) end return "Thank you" end) for i = 1, 8 do local success, value = pcall(nextSquare) print(success, value) end
@file:DependsOn("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1") import kotlinx.coroutines.* runBlocking { repeat(5) { launch { println("Coroutine $it running on ${Thread.currentThread().name}.") delay((1000L..5000L).random()) println("Coroutine $it finished on ${Thread.currentThread().name}.") } } println("All coroutines launched") }
@file:DependsOn( "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1", "com.squareup.okhttp3:okhttp:4.11.0", "org.json:json:20230618", ) import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response import org.json.JSONObject val baseUrl = "https://pokeapi.co/api/v2/pokemon/" val pokemonNames = listOf("ditto", "pikachu", "mew", "weedle", "eevee") data class PokeInfo(val name: String, val height: Int, val weight: Int) suspend fun fetchPokemon(name: String) { println("Fetching $name on ${Thread.currentThread().name}") val request = Request.Builder().url("$baseUrl$name").build() val response = OkHttpClient().newCall(request).execute() if (!response.isSuccessful) { println("Cannot fetch $name: HTTP ${response.code}") return } val jsonObject = JSONObject(response.body?.string() ?: return) println(PokeInfo( jsonObject.getString("name"), jsonObject.getInt("height"), jsonObject.getInt("weight"))) } runBlocking { for (name in pokemonNames) { launch(Dispatchers.IO) { fetchPokemon(name) } } println("The fetches are underway") } println("The fetches are done")
Coroutines are useful in various scenarios:
Here are some questions useful for your spaced repetition learning. Many of the answers are not found on this page. Some will have popped up in lecture. Others will require you to do your own research.
Coming soon
We’ve covered: