-
Notifications
You must be signed in to change notification settings - Fork 98
numcodecs.blosc mutex leaked semaphore warning #230
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
Comments
Thanks @rc-conway. Do you have any suggestions for how to avoid this? |
Could we move it to |
@jakirkham That would the prevent issues caused by having As a just in case |
I'm guessing there is also something weird going on when Cython cleans up this object (or doesn't...). Let's trying moving to |
Added PR ( #234 ) to move initialization of the |
Since PR #234 was close, I had another look on this. The following shows a minimal reproduction of the problem, together with with potential fixes (coming with caveats, discussed below): import multiprocessing as mp
from contextlib import nullcontext
if __name__ == '__main__':
# This must happen before importing blosc,
# and must be guarded by the if.
mp.set_start_method("spawn")
from numcodecs import blosc
### The following line doesn't show anymore leaked semaphores:
# blosc.mutex = mp.get_context("fork").Lock
### Or this, removing the mutex completely, only using
### the _get_use_threads() check
# from contextlib import nullcontext
# blosc.mutex = nullcontext()
def f():
print("inner")
if __name__ == '__main__':
print("outer")
p = mp.Process(target=f)
p.start()
p.join() This outputs
Because of the latter point, I'm wondering if the mutex is actually needed at all. It would be great if someone with more knowledge about the blosc internals could comment on that. In this case simply removing the mutex would be fine, which can be simulated by setting it to Here is some more code I used for further testing:import os
import multiprocessing as mp
if __name__ == '__main__':
# This must happen before importing blosc,
# and must be guarded by the if.
mp.set_start_method("spawn")
from numcodecs import blosc
### The following line doesn't show anymore leaked semaphores:
# blosc.mutex = mp.get_context(method="fork").Lock()
### Or this, removing the mutex completely, only using
### the _get_use_threads() check
from contextlib import nullcontext
blosc.mutex = nullcontext()
def get_random_bytes():
LENGTH = 10**9
return b"\x00" + os.urandom(LENGTH) + b"\x00"
def f():
print("inner")
codec = blosc.Blosc("zstd")
msg = get_random_bytes()
print("use threads (inner)", blosc._get_use_threads(), flush=True)
print("before inner encode", flush=True)
encoded = codec.encode(msg)
print("after inner encode", flush=True)
decoded = codec.decode(encoded)
assert decoded == msg
if __name__ == '__main__':
print("outer")
# When using fork in the global scope,
# one can still use spawn locally,
# without leaked semaphore warnings:
# mp = mp.get_context("spawn")
p = mp.Process(target=f)
p.start()
blosc.set_nthreads(1) # limit threads to allow subprocess to start
codec = blosc.Blosc("lz4")
msg = get_random_bytes()
print("use threads (outer)", blosc._get_use_threads(), flush=True)
print("before outer encode", flush=True)
encoded = codec.encode(msg)
print("after outer encode", flush=True)
decoded = codec.decode(encoded)
assert decoded == msg
p.join() |
FWIW the PR was closed more because of trying to address issue ( zarr-developers/zarr-python#777 ). So a new PR with those changes or other changes could be opened. |
Do you have a preference as to which change, @jakirkham? |
I apologize if I appear to be piling on, but running python 3.9, zarr-py version 2.13.3, I cannot even get this to run without emitting the warning about leaked semaphore objects and hanging (commenting out the
While I agree with the original poster that results do not actually seem to be affected by this problem, a fix would be greatly appreciated. |
No piling on perceived, @danielsf. Extra data points welcome. Ping, @jakirkham. |
Uh oh!
There was an error while loading. Please reload this page.
Minimal, reproducible code sample, a copy-pastable example if possible
import zarr
Problem description
Using
multiprocessing
in a cython context, ifzarr
is in the import space I get a leaked semaphore warning.I suspect the issue is the global
mutex
variable (the lock) innumcodecs.blosc
is possibly being garbage collected prior to the multiprocessing finalizer getting called, so theweakref
is dropped and the lock is never unregistered. This is an issue when used in amultiprocessing
environment. This results in a leaked semaphore warning for me. I don't think there's a functional issue but I would like the warning to go away.https://github.com/zarr-developers/numcodecs/blob/master/numcodecs/blosc.pyx#L78
Version and installation information
Please provide the following:
numcodecs
0.6.4conda
The text was updated successfully, but these errors were encountered: