-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
multiprocessing Manager error: send() called for a closed connection #71936
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
When I use Python 3.5.2 some of the time will be a crash.displayed crash module is python35.dll. I have another question when i using managers lib multiprocessing Maybe have exception. This code is possible to print out the information. Traceback (most recent call last):
File "C:/Users/Administrator/Desktop/Monitor_URL\Monitor_SQL.py", line 44, in execute_select_command
return values
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\multiprocessing\managers.py", line 949, in __exit__
return self._callmethod('release')
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\multiprocessing\managers.py", line 716, in _callmethod
conn.send((self._id, methodname, args, kwds))
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\multiprocessing\connection.py", line 206, in send
self._send_bytes(ForkingPickler.dumps(obj))
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\multiprocessing\connection.py", line 280, in _send_bytes
ov, err = _winapi.WriteFile(self._handle, buf, overlapped=True)
TypeError: WriteFile() argument 1 must be int, not None This maybe seem like a lib problem. |
To diagnose the access violation, it may help if you install the debug binaries and try to reproduce the crash using python_d.exe. Attach the dump file to this issue. Regarding the multiprocessing question, if its a separate issue you need to file it on its own and nosy davin. At first glance, I don't see why the handle is None in the lock's __exit__ method. After you acquire the lock, try logging the connection information. For example: import multiprocessing as mp
import multiprocessing.util
def test(lock):
with lock:
mp.util.info('test:lock:token: %r' % (lock._token,))
mp.util.info('test:lock:handle: %r' % (lock._tls.connection._handle,))
if __name__ == '__main__':
mp.util.log_to_stderr(mp.util.INFO)
lock = mp.Manager().Lock()
p = mp.Process(target=test, args=(lock,))
p.start()
p.join() |
About the crash,python_d.exe crash dump download address is http://o8z0k9748.bkt.clouddn.com/python_d_from_vs_20160813_930A2640.7z Crash dump display,at the
I hope this can be helpful to you. About the multiprocessing question After run,Console output [INFO/SpawnPoolWorker-18] test:lock:token: Token(typeid='Lock', address='\\\\.\\pipe\\pyc-2876-0-n6aj8inv', id='d0b0efa7d0') this problem and crash both the use of multiprocessing lib after appears.Maybe these two issues are related. |
Crashes also happen from Recursion if not careful. Idk why but it happens. Although some of it is probably by not using try / catch probably anywhere in the python source code as a safeguard. I always like try / catch even in C++ as you never know when crap might happen to make things crash. A Perfect Example is a Access violation. (Yes I have this is a Standard for me and it gets me to great quality code) All I know is I like having a lot of Checks (even if not required) that can actually prevent any and all exceptions to begin with. And yes from what I learned from experiance myself. Always use try and catch anything before it is to late will help you in the long run. (not to mention I blame Microsoft for not replacing their current Windows Update for when Updates Fail with a Detailed list of the names of the update(s) that failed and a description of what the reason is without Error code(s) as the Codes does not tell crap about why they failed. So, yeah I point my fingers at whoever wrote Windows Update, to fix their crap. As this is a issue in windows 7 SP1, 8, 8.1, and 10.) |
Decorator: In python code you generally want to let the exception bubble up so that you can see what the error was. Sometimes you do want to catch general errors, but mostly you don't. As for C++ try/catch, CPython is written in C, not C++. So, your comment doesn't really have any relevance to this issue, I'm afraid. |
I can confirm that I also get the same crash. |
I do know for sure the crash happens in python.exe and blames ntdll.dll for it. |
To Decorater About the multiprocessing question,I would like to add some information. My code uses a multiprocessing Pool,I used multiprocessing.util.debug opened the debug information.debug information is as follows. [DEBUG/SpawnPoolWorker-7] thread 'MainThread' does not own a connection
[DEBUG/SpawnPoolWorker-7] making connection to manager
[DEBUG/SyncManager-2] starting server thread to service 'SpawnPoolWorker-7'
[INFO/SpawnPoolWorker-4] test:lock:token: Token(typeid='Lock', address='\\\\.\\pipe\\pyc-3816-0-95051ql_', id='e44c9bc720')
[INFO/SpawnPoolWorker-4] test:lock:handle: 712
[INFO/SpawnPoolWorker-7] test:lock:token: Token(typeid='Lock', address='\\\\.\\pipe\\pyc-3816-0-95051ql_', id='e44c9bc720')
[INFO/SpawnPoolWorker-7] test:lock:handle: 768
[DEBUG/SpawnPoolWorker-7] DECREF 'e44c9bc720'
[INFO/SpawnPoolWorker-4] leave:lock:token: Token(typeid='Lock', address='\\\\.\\pipe\\pyc-3816-0-95051ql_', id='e44c9bc720')
[DEBUG/SpawnPoolWorker-7] thread 'MainThread' has no more proxies so closing conn
[DEBUG/SpawnPoolWorker-7] DECREF 'b0182059f8'
[DEBUG/SyncManager-2] got EOF -- exiting thread serving 'SpawnPoolWorker-7'
[DEBUG/SpawnPoolWorker-4] INCREF 'e44c9bc720'
handle is closed
'ForkAwareLocal' object has no attribute 'connection'
[DEBUG/SpawnPoolWorker-7] thread 'MainThread' has no more proxies so closing conn
Traceback (most recent call last):
File "C:/Users/Administrator/Desktop/Monitor_URL\Monitor_SQL.py", line 51, in execute_select_command
conn.close()
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\multiprocessing\managers.py", line 949, in __exit__
return self._callmethod('release')
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\multiprocessing\managers.py", line 716, in _callmethod
conn.send((self._id, methodname, args, kwds))
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\multiprocessing\connection.py", line 204, in send
self._check_closed()
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\multiprocessing\connection.py", line 136, in _check_closed
raise OSError("handle is closed")
OSError: handle is closed
[INFO/SpawnPoolWorker-7] Exception:lock:token: Token(typeid='Lock', address='\\\\.\\pipe\\pyc-3816-0-95051ql_', id='e44c9bc720')
[INFO/SpawnPoolWorker-7] Exception process:lock:token: Token(typeid='Lock', address='\\\\.\\pipe\\pyc-3816-0-95051ql_', id='e44c9bc720')
[DEBUG/SyncManager-1] got EOF -- exiting thread serving 'SpawnPoolWorker-7'
[DEBUG/SpawnPoolWorker-4] INCREF 'b0182059f8'
[DEBUG/SpawnPoolWorker-4] DECREF 'b0182059f8'
[DEBUG/SpawnPoolWorker-7] INCREF 'e44c9bc720' This time the message and not the same,From the information looks like two processes simultaneously locking the same lock object, and then release happened the problems.I do not know if this is correct, |
I use code that does multithreading to from a library that uses ffmpeg for exact it makes daemon threads so it could be from that. |
I try to change the multiprocessing lib codes,upload the file is debugger display.I try to used while loop make sure connection hanle value is not none,but connection hanle value will still becomes none. |
today,Find a new crash
|
A similar situation also occurs in the following Linux,A similar situation on stackoverflow |
Does this ticket track the issue in its title or the native crash? If it's the latter, is there a new ticket for the None _handle or shall I create one? |
So, I'm experiencing the issue in the title, too. The pipe handle stays valid for between 5 and 60 minutes, then it goes None when written to. I'm far from understanding that code, but this crude re-connect code seems to solve the issue for me: In BaseProxy._callmethod, I changed: conn.send((self._id, methodname, args, kwds)) to:
|
Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection will be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task. Finalizers should be processed after each task is finished, because all proxies of shared objects will lost their references in the next task. Also, BaseProxy does not count references well.
Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection will be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task. BaseProxy does not count references well.
Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection will be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task. BaseProxy does not count references well.
I can consistently reproduce this problem (unfortunately with a third party library that I maintain) on Python 3.12.3 on Ubuntu. The code: from concurrent.futures import ProcessPoolExecutor
from pipefunc import pipefunc, Pipeline
for _ in range(100):
@pipefunc(output_name="c", cache=True)
def f(a, b):
return a + b
pipeline = Pipeline([f], cache_type="lru")
func = pipeline.func("c")
sequence = 100 * [{"a": 2, "b": 3}]
with ProcessPoolExecutor(max_workers=1) as executor:
results = executor.map(func.call_with_dict, sequence)
list(results) Which outputs:
I applied the patch in #98274 which seems to have solve the problem. |
Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection would be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task, and a new object is allocated that shares the id() of a previously deleted one. Instead of using the id() of the token (or the proxy), use a unique, non-reusable number. Co-Authored-By: Akinori Hattori <[email protected]>
Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection would be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task, and a new object is allocated that shares the id() of a previously deleted one. Instead of using the id() of the token (or the proxy), use a unique, non-reusable number. Co-Authored-By: Akinori Hattori <[email protected]>
* gh-71936: Fix race condition in multiprocessing.Pool Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection would be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task, and a new object is allocated that shares the id() of a previously deleted one. Instead of using the id() of the token (or the proxy), use a unique, non-reusable number. Co-Authored-By: Akinori Hattori <[email protected]>
Merged in main. I'll watch the buildbots for a bit before backporting. |
@encukou, sorry that it took me this long to reply but using the code in #71936 (comment) and your patch from #124973, I can no longer reproduce the problem! Thanks a lot! |
…124973) * pythongh-71936: Fix race condition in multiprocessing.Pool Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection would be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task, and a new object is allocated that shares the id() of a previously deleted one. Instead of using the id() of the token (or the proxy), use a unique, non-reusable number. (cherry picked from commit ba088c8) Co-authored-by: Petr Viktorin <[email protected]> Co-Authored-By: Akinori Hattori <[email protected]>
…124973) * pythongh-71936: Fix race condition in multiprocessing.Pool Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection would be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task, and a new object is allocated that shares the id() of a previously deleted one. Instead of using the id() of the token (or the proxy), use a unique, non-reusable number. (cherry picked from commit ba088c8) Co-authored-by: Petr Viktorin <[email protected]> Co-Authored-By: Akinori Hattori <[email protected]>
… (GH-126870) Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection would be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task, and a new object is allocated that shares the id() of a previously deleted one. Instead of using the id() of the token (or the proxy), use a unique, non-reusable number. (cherry picked from commit ba088c8) Co-authored-by: Petr Viktorin <[email protected]> Co-authored-by: Akinori Hattori <[email protected]>
… (GH-126869) Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection would be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task, and a new object is allocated that shares the id() of a previously deleted one. Instead of using the id() of the token (or the proxy), use a unique, non-reusable number. (cherry picked from commit ba088c8) Co-authored-by: Petr Viktorin <[email protected]> Co-authored-by: Akinori Hattori <[email protected]>
The backports are in. Thank you to everyone involved! |
…124973) * pythongh-71936: Fix race condition in multiprocessing.Pool Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection would be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task, and a new object is allocated that shares the id() of a previously deleted one. Instead of using the id() of the token (or the proxy), use a unique, non-reusable number. Co-Authored-By: Akinori Hattori <[email protected]>
…124973) * pythongh-71936: Fix race condition in multiprocessing.Pool Proxes of shared objects register a Finalizer in BaseProxy._incref(), and it will call BaseProxy._decref() when it is GCed. This may cause a race condition with Pool(maxtasksperchild=None) on Windows. A connection would be closed and raised TypeError when a GC occurs between _ConnectionBase._check_writable() and _ConnectionBase._send_bytes() in _ConnectionBase.send() in the second or later task, and a new object is allocated that shares the id() of a previously deleted one. Instead of using the id() of the token (or the proxy), use a unique, non-reusable number. Co-Authored-By: Akinori Hattori <[email protected]>
Uh oh!
There was an error while loading. Please reload this page.
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
Linked PRs
The text was updated successfully, but these errors were encountered: