You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MacOS运行Python multiprocessing代码报OSError 28设备空间不足

提问:macOS运行Python multiprocessing多进程代码触发OSError: [Errno 28] No space left on device

我在macOS系统运行Python multiprocessing多进程示例代码时,触发了错误OSError: [Errno 28] No space left on device。

ENOSPC(即“设备空间不足”)错误会在I/O操作关联的数据或元数据因空间不足无法写入时触发,它不一定代表磁盘物理空间不足,也可能指逻辑空间(如最大文件长度限制)、特定数据结构空间、地址空间不足。例如vfat文件系统的目录表空间不足、inode耗尽时也会抛出该错误,大致含义为“找不到可写入的位置”。
我不理解的是,我下方的代码中并没有写入文件的操作,为什么会触发该错误?恳请大家提供帮助。

示例代码

#! /usr/bin/env python3
import sys
import os
import multiprocessing as mp
import time


def foo_pool(x):
    time.sleep(2)
    return x*x

result_list = []
def log_result(result):
    result_list.append(result)
    print(result)

def apply_async_with_callback():
    pool = mp.Pool()
    for i in range(10):
        pool.apply_async(foo_pool, args = (i, ), callback = log_result)
    pool.close()
    pool.join()
    print(result_list)

if __name__ == '__main__':
    apply_async_with_callback()

完整报错信息

python3 test.py
Traceback (most recent call last):
  File "test.py", line 32, in <module>
    apply_async_with_callback()
  File "test.py", line 23, in apply_async_with_callback
    pool = mp.Pool()
  File "/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/context.py", line 119, in Pool
    return Pool(processes, initializer, initargs, maxtasksperchild,
  File "/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/pool.py", line 191, in __init__
    self._setup_queues()
  File "/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/pool.py", line 343, in _setup_queues
    self._inqueue = self._ctx.SimpleQueue()
  File "/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/context.py", line 113, in SimpleQueue
    return SimpleQueue(ctx=self.get_context())
  File "/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/queues.py", line 342, in __init__
    self._rlock = ctx.Lock()
  File "/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/context.py", line 68, in Lock
    return Lock(ctx=self.get_context())
  File "/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/synchronize.py", line 162, in __init__
    SemLock.__init__(self, SEMAPHORE, 1, 1, ctx=ctx)
  File "/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/multiprocessing/synchronize.py", line 57, in __init__
    sl = self._semlock = _multiprocessing.SemLock(
OSError: [Errno 28] No space left on device

回答

该错误与磁盘剩余空间无关,根因为系统POSIX信号量配额耗尽。
从报错栈可以看到,错误发生在创建_multiprocessing.SemLock对象的阶段:macOS作为BSD衍生系统,对POSIX信号量的全局分配数量有严格的默认上限。Python的multiprocessing模块初始化进程池时,会为内部的任务队列、进程同步锁创建多个POSIX信号量对象,当系统没有剩余的信号量配额可以分配时,内核就会返回ENOSPC错误,对应你看到的No space left on device提示。
ENOSPC错误本身就不只对应磁盘物理空间不足的场景,内核层面的系统资源配额耗尽也会触发该错误,和你的代码有没有写入文件的操作没有关系。

解决方案

  • 最快修复:重启电脑,所有未被释放的残留信号量会被内核自动清理,绝大多数场景重启后即可正常运行代码。
  • 手动清理残留信号量:
    1. 执行命令ipcs -s列出当前系统所有的信号量
    2. 找到所有者为你当前登录用户的无用信号量条目
    3. 执行ipcrm -s <信号量ID>逐个删除即可
  • 代码优化:
    初始化进程池时不要使用默认的进程数,显式指定更小的进程数,避免一次性申请过多信号量,比如可以把pool = mp.Pool()修改为pool = mp.Pool(processes=4),进程数按需设置即可,不需要超过设备的CPU核心数。
  • 永久调整配额(仅推荐专业用户操作):
    可以通过修改macOS内核参数调高信号量上限,编辑/etc/sysctl.conf添加以下配置,重启后生效:
    kern.sysv.semmni=1024
    kern.sysv.semmns=2048
    

内容的提问来源于stack exchange,提问作者endo.anaconda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 02:54:09