-
Notifications
You must be signed in to change notification settings - Fork 55
Description
Describe the bug
When waiting to read from an openpmd_api.Series.read_iterations that was created from an ADIOS2 stream, the GIL is never released.
This creates a race condition when asynchronously reading via threading.Thread and adding to a queue.Queue: if data is not consumed fast enough and a read out of the stream ever starts to block because the Queue is full, the Python process cannot continue execution because the GIL is forever kept on the openPMD side.
Using multiprocessing.{Process,Queue} is a way around this problem.
Pseudocode
from queue import Queue
from threading import Thread
import time
import openpmd_api
def read_queued(stream, queue):
for x in iter(stream.read_iterations()):
queue.put(x)
stream = openpmd_api.Series('stream.sst', openpmd_api.Access_Type.read_only)
queue = Queue(maxsize=3)
reader_thread = Thread(target=read_queued, args=(stream, queue))
reader_thread.start()
for i in range(20):
queue.get()
# This duration must be larger than what reading a data point from the stream takes.
time.sleep(5)
print('I'll never be reached!')
reader_thread.join()Expected behavior
If the read blocks while waiting for stream data, the GIL needs to be released. (Related Python doc and PyBind11 doc.)
Software Environment
- version of openPMD-api: 0.15.0-dev
- installed openPMD-api via: from source
- operating system: Rocky Linux 8
- machine: JUWELS Booster
- name and version of Python implementation: CPython 3.9.6
- version of ADIOS2: 3d498e5c423ec3830264b1cfdf7c0182dd0bddc7
- name and version of MPI: ParaStationMPI 5.5.0
Additional context
Sorry for no example, don't know how to create a minimal ADIOS2 stream.