From a27145e8ebd66500e6161c37a99620c8c22c79c2 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Wed, 3 Aug 2022 16:52:22 -0500 Subject: [PATCH] Reverse order and edit narrative to highlight potential issues with Distributed and to link to the relevant manual entries --- docs/src/manual/async.md | 79 ++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/docs/src/manual/async.md b/docs/src/manual/async.md index 349a340c..2d144792 100644 --- a/docs/src/manual/async.md +++ b/docs/src/manual/async.md @@ -1,13 +1,16 @@ # Asynchronous UI It is possible to perform background computation without interfering with user interface -responsiveness either using separate processes or using multithreading. Use of a separate -process includes slightly more overhead but is also more robust. +responsiveness either using multithreading or using separate processes. Use of a separate +process includes slightly more overhead but also enusres user interface responsiveness more +robustly. -Here is an example using a separate process to offload the work. +Here is an example using [threads](https://docs.julialang.org/en/v1/manual/multi-threading/). +Notice that this example will freeze the UI during computation unless Julia is run with two +or more threads (`julia -t2` on the command line). ```julia -using Gtk, Distributed +using Gtk btn = GtkButton("Start") sp = GtkSpinner() @@ -18,37 +21,39 @@ grid[1,1] = btn grid[2,1] = sp grid[1:2,2] = ent -id = addprocs(1)[1] - signal_connect(btn, "clicked") do widget start(sp) - @async begin + Threads.@spawn begin - # Offload work to a separate process and block until it is done. - counter = @fetchfrom id begin - stop_time = time() + 3 - counter = 0 - while time() < stop_time - counter += 1 - end - counter + # Do work + stop_time = time() + 3 + counter = 0 + while time() < stop_time + counter += 1 end - # We are still in the main thread so it is okay to directly access widgets - stop(sp) - set_gtk_property!(ent, :text, "I counted to $counter in a separate process!") + # Interacting with GTK from a thread other than the main thread is + # generally not allowed, so we register an idle callback instead. + Gtk.GLib.g_idle_add(nothing) do user_data + stop(sp) + set_gtk_property!(ent, :text, "I counted to $counter in a thread!") + Cint(false) + end end end -win = GtkWindow(grid, "Distributed", 200, 200) +win = GtkWindow(grid, "Threads", 200, 200) showall(win) ``` -And here is an example using threads. Notice that this example will freeze the UI during -computation unless Julia is run with two or more threads (`julia -t2` on the command line). + +Here is an example using a separate process to offload the work. This toy example is +fairly straightforward, but things can get more complex if the offloaded task is more +complex. See the [manual](https://docs.julialang.org/en/v1/manual/distributed-computing/) +for details. ```julia -using Gtk +using Gtk, Distributed btn = GtkButton("Start") sp = GtkSpinner() @@ -59,27 +64,29 @@ grid[1,1] = btn grid[2,1] = sp grid[1:2,2] = ent +id = addprocs(1)[1] + signal_connect(btn, "clicked") do widget start(sp) - Threads.@spawn begin + @async begin - # Do work - stop_time = time() + 3 - counter = 0 - while time() < stop_time - counter += 1 + # Offload work to a separate process and block until it is done. + counter = @fetchfrom id begin + stop_time = time() + 3 + counter = 0 + while time() < stop_time + counter += 1 + end + counter end - # Interacting with GTK from a thread other than the main thread is - # generally not allowed, so we register an idle callback instead. - Gtk.GLib.g_idle_add(nothing) do user_data - stop(sp) - set_gtk_property!(ent, :text, "I counted to $counter in a thread!") - Cint(false) - end + # We are still in the main thread so it is okay to directly access widgets + stop(sp) + set_gtk_property!(ent, :text, "I counted to $counter in a separate process!") end end -win = GtkWindow(grid, "Threads", 200, 200) +win = GtkWindow(grid, "Distributed", 200, 200) showall(win) ``` +