Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple async_executes may not always execute in sequence? #278

Open
tanmaykm opened this issue Aug 18, 2023 · 0 comments
Open

Multiple async_executes may not always execute in sequence? #278

tanmaykm opened this issue Aug 18, 2023 · 0 comments

Comments

@tanmaykm
Copy link
Contributor

The docstring for async_execute mentions:

Only one `AsyncResult` can be active on a [`Connection`](@ref) at once.
If multiple `AsyncResult`s use the same `Connection`, they will execute serially.

The actual implementation does this for synchronization in the method:

async_result.result_task = @async lock(jl_conn) do

But it is not clear if that's something that can guarantee the desired behavior. The doubt is based on these questions:

  • Are tasks spawned guaranteed to start executing in the order in which they were spawned?
  • And are locks guaranteed to be granted in the same order in which they were requested?

In this example below, that is what happens:

julia> using Base.Threads

julia> function test1()
           lck = Threads.Condition()
           val = 10
           @sync begin
               for idx in 1:50
                   @async begin
                       lock(lck) do
                           val = idx
                       end
                   end     
               end
           end
           println("val: $val")
       end
test1 (generic function with 1 method)

julia> test1()
val: 50

julia> test1()
val: 50

But making the task yield randomly makes the result different every time:

julia> function test2()
           lck = Threads.Condition()
           val = 10
           @sync begin
               for idx in 1:50
                   @async begin
                       sleep(rand())
                       lock(lck) do
                           val = idx
                       end
                   end     
               end
           end
           println("val: $val")
       end
test2 (generic function with 1 method)

julia> test2()
val: 45

julia> test2()
val: 8

The question is in absence of any random yield (as in test2), is the execution order (as in test1) something that is guaranteed in Julia?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant