Repository navigation
Fix forked DataLoader workers hanging after the parent iterated the dataset - #48
Merged
Merged
Conversation
Documentation build overview
|
…ataLoader workers no longer hang after the parent iterated, and leave them out of the pickled state.
avgvi
force-pushed
the
fix/fork-after-iter
branch
from
October 12, 2026 03:24
49cc4c8 to
e030b0d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Starting
forkDataLoader workers after the parent process has iterated the dataset hangs. A forked child inherits the parent'sThreadPoolExecutor, whose idle-thread bookkeeping claims workers that do not exist in the child, so the download and ready threads submitted in__iter__never run and the yield loop waits forever. If the parent is in the middle of an epoch, the child also callsexit()on the inherited iterator and waits for threads it does not have.0.13.0 with filelock 3.31 or newer failed at once with
RuntimeError: ... inherited across fork. #26 recreates the locks per process, which removed that error and exposed the hang; it is the known issue listed in the 0.14.0 release notes.A dataset that has iterated also no longer pickled (
TypeError: cannot pickle '_queue.SimpleQueue' object), sospawnandforkserverworkers after parent use failed as well, in 0.13.0 too.Fix
__iter__keys the thread pool, event and iterator onos.getpid(): a new process gets fresh ones and drops the inherited iterator.__getstate__leaves the pool, event and iterator out of the pickled state, like the cache filelock.Tests
test_dataloader_after_parent_usereplaces the fork-onlytest_dataloader_fork_after_parent_use: fork, spawn and forkserver, each afterdataset[0], a full epoch and an epoch in progress, withDataLoader(timeout=60)so a regression fails instead of hanging.test_streaming,test_evictionandtest_barrierpass on Linux 3.12 (226 tests); the nine start-method cases also pass on macOS.Found by the differential test of 0.14.1 against 0.13.0.