multiprocessing.Event.set() can deadlock when called from a signal handler or trace function
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Python
- Star
- 77.2k
- Fork
- 35.9k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
Bug report
Bug description:
multiprocessing.Event.set() will acquire a lock when setting the internal flag. multiprocessing.Event.is_set() will acquire the same lock when checking the flag. Thus if a signal handler calls .set() when .is_set() is running on the same process, there will be a deadlock.
multiprocessing.Event uses a regular non-reentrantlock lock. This should be changed to a reentrant lock. Please see the pull request.
Thanks for all the work on the Python programming language. I appreciate all your efforts highly.
Kind regards.
Example program below that (sometimes) deadlocks. On my machine I typically need to run it less than 10 times before a deadlock occurs. Also included in the code block is a sample stacktrace.
import faulthandler
import multiprocessing
import os
import signal
def run_buggy():
shutdown_event = multiprocessing.Event()
def sigterm_handler(_signo, _stack_frame):
try:
print(f'sigterm_handler running')
shutdown_event.set()
finally:
print(f'sigterm_handler done')
signal.signal(signal.SIGTERM, sigterm_handler)
signal.signal(signal.SIGINT, sigterm_handler)
faulthandler.register(signal.SIGUSR1)
print(f'Running process with PID {os.getpid()}')
print(f'Dump the stack by executing:')
print(f'kill -SIGUSR1 {os.getpid()}')
print(f'Try to kill this process with CTRL-C or kill {os.getpid()}')
while not shutdown_event.is_set():
pass
if __name__ == '__main__':
run_buggy()
# Sample stacktrace:
# Current thread 0x00000001ed74cf40 (most recent call first):
# File "/Users/ire/code/cpython/Lib/multiprocessing/synchronize.py", line 95 in __enter__
# File "/Users/ire/code/cpython/Lib/multiprocessing/synchronize.py", line 237 in __enter__
# File "/Users/ire/code/cpython/Lib/multiprocessing/synchronize.py", line 342 in set
# File "/Users/ire/code/cpython/./bug.py", line 13 in sigterm_handler
# File "/Users/ire/code/cpython/Lib/multiprocessing/synchronize.py", line 95 in __enter__
# File "/Users/ire/code/cpython/Lib/multiprocessing/synchronize.py", line 237 in __enter__
# File "/Users/ire/code/cpython/Lib/multiprocessing/synchronize.py", line 335 in is_set
# File "/Users/ire/code/cpython/./bug.py", line 25 in run_buggy
# File "/Users/ire/code/cpython/./bug.py", line 29 in <module>
CPython versions tested on:
3.11, 3.12, CPython main branch
Operating systems tested on:
Linux, macOS
Linked PRs
- gh-126437
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu trong Lib/multiprocessing/synchronize.py tại các nhánh is_set() và set() được tham chiếu trong stack trace, sau đó tái hiện vấn đề bằng chương trình ví dụ và signal handler. Xem xét PR gh-126437 được liên kết và các bài kiểm thử của nó; được coi là hoàn tất khi Event không còn bị deadlock khi set() được gọi từ handler hoặc hàm trace.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- python
- Lĩnh vực
- operating-systems
- Loại issue
- Lỗi
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức phù hợp với người mới
- 25/100