-
Notifications
You must be signed in to change notification settings - Fork 142
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
Design of clear_task_threads #1057
Design of clear_task_threads #1057
Comments
Ok, I've dug back into this and here's my understanding:
One easy mitigation, if possible, is to ensure that The closure inputs reference, however, is unavoidable as far as I understand. This leads us to consider alternative solutions, like JuliaLang/julia#47405, which basically tries to treat Tasks that have finished as weak refs, or the The original definition in CSV.jl was: function clear_thread_states()
Threads.@threads :static for _ in 1:Threads.nthreads()
Timer(_Returns(nothing), 0; interval = 1)
end
end But @iamed2 pointed out that this causes problems when making a call like The follow up definition tried to avoid this by checking 1st if the Having further reviewed, I agree that having the Another alternative that I may try is trying to do the weak referencing of closure inputs ourselves; so we would put all of our closure input arguments into a |
Also did a similar writeup + show of a potential new approach here |
Most complete explanation is [here](JuliaLang/julia#40626 (comment)). Also discussed [here](#1057). This PR proposes an alternative solution to `clear_thread_states` where that approach can be problematic (interferring with global thread state, not working as expected in nested spawned tasks, etc.). The previous definition also started unending `Timer` tasks that could build up over time. The approach in this PR is to wrap spawned task closure arguments in `WeakRef` to allow them to be GCed as expected once the tasks are finished.
PR up: #1058 |
…e argumetns in WeakRef Fixes JuliaData/CSV.jl#1057. Works around current Julia limitation here: JuliaLang/julia#40626. `@wkspawn` acts just like `Threads.@spawn`, except for mutable, interpolated arguments in the spawned expression, they will also be transparently wrapped as `WeakRef`s, then immediately unwrapped within the spawn block. This avoids the `Task` closure capturing mutable arguments in a more permanent way and preventing their collection later, even after there are no more program references to the mutable argument.
#10) * Add new `@wkspawn` macro for wrapping mutable `Threads.@spawn` closure argumetns in WeakRef Fixes JuliaData/CSV.jl#1057. Works around current Julia limitation here: JuliaLang/julia#40626. `@wkspawn` acts just like `Threads.@spawn`, except for mutable, interpolated arguments in the spawned expression, they will also be transparently wrapped as `WeakRef`s, then immediately unwrapped within the spawn block. This avoids the `Task` closure capturing mutable arguments in a more permanent way and preventing their collection later, even after there are no more program references to the mutable argument. * Compat * fix * try lots of gc * Fix * Run with threads
…#1058) * Use WeakRefs for spawned tasks to avoid holding unexpected references Most complete explanation is [here](JuliaLang/julia#40626 (comment)). Also discussed [here](#1057). This PR proposes an alternative solution to `clear_thread_states` where that approach can be problematic (interferring with global thread state, not working as expected in nested spawned tasks, etc.). The previous definition also started unending `Timer` tasks that could build up over time. The approach in this PR is to wrap spawned task closure arguments in `WeakRef` to allow them to be GCed as expected once the tasks are finished. * Try putting gc preserve inside Threads.spawn block * Outside GC preserve manual sync block * Make Context mutable so it gets preserved properly * Only wrap in WeakRef if mutable * oops * Use `@wkspawn` from WorkerUtilities.jl package * 1.6 compat
In
CSV.jl/src/utils.jl
Line 629 in 35e8402
@quinnj I do not understand two things:
Timer
here? I understand why it is proposed in Thread-local current_task keeps garbage alive JuliaLang/julia#40626 (as it would be a solution in general for Base Julia) but why call this function every second forever from CSV.jl? I would think it is enough to call it once.The text was updated successfully, but these errors were encountered: