在Gramine中运行multiprocessing Queue报错:No such file or directory
问题:Gramine环境中Python multiprocessing.Queue报错FileNotFoundError
问题背景
在Gramine环境运行Python多进程代码时,创建multiprocessing.Queue抛出FileNotFoundError,相关文件及报错详情如下:
清单文件(manifest)
loader.entrypoint = "file:{{ gramine.libos }}" libos.entrypoint = "{{ entrypoint }}" loader.log_level = "debug" loader.env.LD_LIBRARY_PATH = "/lib:/usr/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}" loader.env.OMP_NUM_THREADS = "8" loader.insecure__use_cmdline_argv = true loader.insecure__use_host_env = true sgx.nonpie_binary = true fs.mounts = [ { uri = "file:{{ gramine.runtimedir() }}", path = "/lib" }, { uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" }, { uri = "file:/usr", path = "/usr" }, { uri = "file:/etc", path = "/etc" }, { uri = "file:{{ pillow_path }}", path = "{{ pillow_path }}" }, { type = "tmpfs", path = "/tmp" }, ] sgx.enclave_size = "1G" sgx.max_threads = 32 sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} sgx.trusted_files = [ "file:{{ gramine.libos }}", "file:{{ entrypoint }}", "file:{{ gramine.runtimedir() }}/", "file:{{ arch_libdir }}/", "file:/usr/{{ arch_libdir }}/", "file:{{ python.stdlib }}/", "file:{{ python.distlib }}/", "file:{{ pillow_path }}", "file:{{ python.get_path('stdlib', vars={'installed_base': '/usr/local'}) }}/", "file:test.py", ]
Python程序文件(test.py)
import multiprocessing def worker(queue): item = queue.get() print("Worker received:", item) if __name__ == "__main__": queue = multiprocessing.Queue() process = multiprocessing.Process(target=worker, args=(queue,)) process.start() item = "Hello, multiprocessing!" queue.put(item) process.join() while not queue.empty(): item = queue.get() print("Item in queue:", item)
报错信息
Traceback (most recent call last): File "test.py", line 8, in <module> queue = multiprocessing.Queue() File "/usr/lib/python3.8/multiprocessing/context.py", line 103, in Queue return Queue(maxsize, ctx=self.get_context()) File "/usr/lib/python3.8/multiprocessing/queues.py", line 42, in __init__ self._rlock = ctx.Lock() File "/usr/lib/python3.8/multiprocessing/context.py", line 68, in Lock return Lock(ctx=self.get_context()) File "/usr/lib/python3.8/multiprocessing/synchronize.py", line 162, in __init__ SemLock.__init__(self, SEMAPHORE, 1, 1, ctx=ctx) File "/usr/lib/python3.8/multiprocessing/synchronize.py", line 57, in __init__ sl = self._semlock = _multiprocessing.SemLock( FileNotFoundError: [Errno 2] No such file or directory
原因分析与解答
你的猜测正确,Gramine当前(截至2024年)不完全支持Python的multiprocessing模块基于fork/spawn的多进程模型,尤其是依赖系统级IPC原语的组件(比如Queue背后的SemLock)。
具体原因:
- Python的
multiprocessing.Queue依赖底层的_multiprocessing.SemLock,该组件需要访问宿主系统的/dev/shm共享内存文件系统,以及创建匿名管道、信号量等原生IPC资源。 - Gramine作为用户态LibOS,对Linux原生IPC机制的支持有限;在SGX enclave模式下,进程隔离和资源访问受到严格限制,无法直接复用宿主系统的IPC设施,因此触发
FileNotFoundError。
替代方案
- 改用线程模型:如果不需要严格的进程隔离,使用
multiprocessing.dummy(基于线程的多进程模拟)或直接用threading模块,线程间的队列可以正常工作。 - 手动实现IPC:通过Gramine支持的资源(如已配置的
/tmptmpfs挂载点),用文件、socket等方式实现进程间数据传递。 - 利用Gramine多线程支持:你已配置
sgx.max_threads=32,将并行逻辑改为多线程模型,可避开进程IPC的限制。 - 关注版本更新:后续Gramine版本可能逐步完善对
multiprocessing的支持,可留意官方更新日志。
内容的提问来源于stack exchange,提问作者Yanmeng Smart
相关产品推荐
相关产品推荐

