Overview
When using nbdev on macOS, the following error occurred.
nbdev_prepare
objc[48348]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called.
objc[48348]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
Traceback (most recent call last):
...
concurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.
This is a personal note on addressing this error.
Solution
Running the following resolved the issue and the command worked without problems.
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
Summary
I hope this serves as a useful reference for those encountering the same issue.
Below is a reference answer from ChatGPT.
Answer
This error message can occur when using Python’s multiprocessing in certain macOS environments. Specifically, when using Python’s concurrent.futures or multiprocessing libraries on macOS, problems can arise when fork() is called to spawn new processes.
Details
The key point in the error message is that fork() was called during the initialization of the Objective-C string class (__NSCFConstantString). fork() is a UNIX system call that duplicates the current process to create a new one, but if Objective-C libraries or other initializations haven’t completed during this duplication, problems can occur in the new process.
On macOS, particularly when Objective-C or other system libraries are involved, issues are likely to occur when initialization processing is performed on threads other than the main thread after a process fork(). This is because the new process, created by fork(), attempts initialization in an unexpected state.
Solution
The export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES presented as a solution is an environment variable to work around this problem. Setting this disables the check that considers initialization after fork() to be unsafe, thereby avoiding the error.
However, this is merely a workaround and not a fundamental solution, so it should be used with caution and understanding of its implications. Since it carries the risk of processes terminating unexpectedly, it is recommended to use it only when no other solution is available.