How Does The Gil Handle Chunked I/o Read/write?
Solution 1:
From what I can see in the BytesIO
type's source code, the GIL is not released during a call to BytesIO.write
, since it's just doing a quick memory copy. It's only for system calls that may block that it makes sense for the GIL to be released.
There probably is such a syscall in the __next__
method of the r.iter_content
generator (when data is read from a socket), but there's none on the writing side.
But I think your question reflects an incorrect understanding of what it means for a builtin function to release the GIL when doing a blocking operation. It will release the GIL just before it does the potentially blocking syscall. But it will reacquire the GIL it before it returns to Python code. So it doesn't matter how many such GIL releasing operations you have in a loop, all the Python code involved will be run with the GIL held. The GIL is never released by one operation and reclaimed by different one. It's both released and reclaimed for each operation, as a single self-contained step.
As an example, you can look at the C code that implements writing to a file descriptor. The macro Py_BEGIN_ALLOW_THREADS
releases the GIL. A few lines later, Py_END_ALLOW_THREADS
reacquires the GIL. No Python level runs in between those steps, only a few low-level C assignments regarding errno
, and the write
syscall that might block, waiting on the disk.
Post a Comment for "How Does The Gil Handle Chunked I/o Read/write?"