Skip to content

Commit

Permalink
Merge a27145e into 573121e
Browse files Browse the repository at this point in the history
  • Loading branch information
LilithHafner committed Aug 3, 2022
2 parents 573121e + a27145e commit c252536
Showing 1 changed file with 68 additions and 17 deletions.
85 changes: 68 additions & 17 deletions docs/src/manual/async.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# Asynchronous UI

Here is an example of an asynchronous update of the user interface. Since
Julia has currently no possibility of multithreading we use a second process
to offload the work. The example is just a proof of principle.
It is possible to perform background computation without interfering with user interface
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 [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
Expand All @@ -16,26 +21,72 @@ grid[1,1] = btn
grid[2,1] = sp
grid[1:2,2] = ent

signal_connect(btn, "clicked") do widget
start(sp)
Threads.@spawn begin

# Do work
stop_time = time() + 3
counter = 0
while time() < stop_time
counter += 1
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
end
end

win = GtkWindow(grid, "Threads", 200, 200)
showall(win)
```


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, Distributed

btn = GtkButton("Start")
sp = GtkSpinner()
ent = GtkEntry()

grid = GtkGrid()
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)
@Gtk.sigatom begin
@async begin
s = @fetchfrom id begin
sleep(4)
return "I am back"
end
@Gtk.sigatom begin
stop(sp)
set_gtk_property!(ent,:text,s)
start(sp)
@async 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
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
end
end

win = GtkWindow(grid, "Progress Bar", 200, 200)
win = GtkWindow(grid, "Distributed", 200, 200)
showall(win)
```


0 comments on commit c252536

Please sign in to comment.