# Switching tasks mid-write()?

**URL:** <https://discourse.julialang.org/t/switching-tasks-mid-write/60232>\
**Category:** Internals & Design\
**Tags:** bug\
**Created:** [April 29, 2021, 11:08am UTC](https://discourse.julialang.org/t/switching-tasks-mid-write/60232 "2021-04-29T11:08:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![green.nsk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/green.nsk/32/24014_2.png) [@green.nsk](https://discourse.julialang.org/u/green.nsk)\
**Post date:** [April 29, 2021, 11:08am UTC](https://discourse.julialang.org/t/switching-tasks-mid-write/60232/1 "2021-04-29T11:08:05Z")

</div>

I am running into a problem with my logging implementation, and I boiled it down to the following:

```julia
function repro()
       @async write(stderr, "Foo", "\n")
       @async write(stderr, "Bar", "\n")
       nothing
end
repro()

```

100% of the time I get:

```julia
FooBar

```

I appreciate that `write()` can yield, but should it at least complete the write before doing so? Otherwise I have to manually concatenate everything if I want to make sure things stay on the same line.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [April 29, 2021, 11:31am UTC](https://discourse.julialang.org/t/switching-tasks-mid-write/60232/2 "2021-04-29T11:31:33Z")

</div>

You can use `print` instead, which works like you expect ([it locks the `io` and prints everything](https://github.com/JuliaLang/julia/blob/3389940f945d0f942fe353e4dca6c1d4d18f26d1/base/strings/io.jl#L42-L52)). Otherwise you can write everything to a `IOBuffer` and then `write` everything in one go:

```julia
function repro()
    @async begin
        io = IOBuffer()
        write(io, "Foo", "\n")
        write(stderr, take!(io))
    end
    @async begin
        io = IOBuffer()
        write(io, "Bar", "\n")
        write(stderr, take!(io))
    end
    nothing
end
repro()

```

This is the method that the [logging system is using](https://github.com/JuliaLang/julia/blob/3389940f945d0f942fe353e4dca6c1d4d18f26d1/base/logging.jl#L650-L667), for example.

---

<div class="post-metadata">

**Author:** ![green.nsk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/green.nsk/32/24014_2.png) [@green.nsk](https://discourse.julialang.org/u/green.nsk)\
**Post date:** [April 29, 2021, 11:54am UTC](https://discourse.julialang.org/t/switching-tasks-mid-write/60232/3 "2021-04-29T11:54:30Z")

</div>

One other thing I noticed is if I used IOBuffer() instead of stderr I get entirely different thing:

```julia
function repro()
       io = IOBuffer()
       t1 = @async write(io, "Foo", "\n")
       t2 = @async write(io, "Bar", "\n")
       wait(t1)
       wait(t2)
       String(take!(io))
end

repro()

```

I get “Foo\nBar\n” as expected. Same for writing to a file – no interleaving happens there. There must be something special about writing to stderr/stdout, and that seems strange.

Thank you for pointing out `print()` is different. I didn’t realize that, and I could borrow the trick.

I am not entirely sure which is better from performance perspective – allocating a buffer + memcpy() or locking stderr (which will cause some unnecessary task switching, as write() I assume will still yield)

Thanks a lot!

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 29, 2021, 12:18pm UTC](https://discourse.julialang.org/t/switching-tasks-mid-write/60232/4 "2021-04-29T12:18:55Z")

</div>

> [@green.nsk](#):
>
> There must be something special about writing to stderr/stdout, and that seems strange.

There are only certain points where tasks “yield” to each other. IO is one of them.

---

<div class="post-metadata">

**Author:** ![green.nsk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/green.nsk/32/24014_2.png) [@green.nsk](https://discourse.julialang.org/u/green.nsk)\
**Post date:** [April 29, 2021, 12:19pm UTC](https://discourse.julialang.org/t/switching-tasks-mid-write/60232/5 "2021-04-29T12:19:48Z")

</div>

yes, but it yields when writing to stderr, but not to a filestream.
