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

Emscripten项目中SDL2加-pthread编译失败原因及解决方法

问题:Emscripten启用-sUSE_PTHREADS=1编译SDL2时缓存锁冲突失败

CMake配置

set(USE_FLAGS "-sUSE_ZLIB=1 -sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS=['png,jpg'] -O3 -g -sWASM_WORKERS -sUSE_PTHREADS=1" CACHE STRING "Compilation flags" FORCE)

set(LINKING_FLAGS "--preload-file ${ASSETS_PATH}/assets@/assets -sFULL_ES2 -sWASM=1 -sFETCH=1 -sEXIT_RUNTIME=1 -sALLOW_MEMORY_GROWTH=1 -sEXPORTED_FUNCTIONS=['_main','_photoTaken','_malloc','_setNotificationToken','_interceptPushNotification','stackSave','stackRestore','stackAlloc'] -sEXPORTED_RUNTIME_METHODS=[cwrap] -sFORCE_FILESYSTEM=1 -lidbfs.js -O3 -g -sAUDIO_WORKLET=1 -sWASM_WORKERS -sASYNCIFY -sASYNCIFY_STACK_SIZE=131072 -sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS=['png,jpg'] -sWEBAUDIO_DEBUG=1 -sUSE_PTHREADS=1 -sPTHREAD_POOL_SIZE=8 -sPROXY_TO_PTHREAD" CACHE STRING "Linking flags" FORCE)

错误信息

assert 'EM_CACHE_IS_LOCKED' not in os.environ, f'attempt to lock the cache while a parent process is holding the lock ({reason})'
AssertionError: attempt to lock the cache while a parent process is holding the lock (sysroot/lib/wasm32-emscripten/libSDL2.a)
em++: error: subprocess 1/19 failed (returned 1)! (cmdline: /../../emsdk/upstream/emscripten/emcc -c /../../emsdk/upstream/emscripten/cache/ports/sdl2_image/SDL_image-release-2.6.0/IMG.c -o /Users/olegparamonov/emsdk/upstream/emscripten/cache/ports-builds/sdl2_image/IMG.c.o -g -sSTRICT -Werror -O2 -I/../../emsdk/upstream/emscripten/cache/ports/sdl2_image/SDL_image-release-2.6.0 -O2 -sUSE_SDL=2 -Wno-format-security -DLOAD_JPG -DLOAD_PNG -sUSE_LIBPNG -sUSE_LIBJPEG)

原因分析

该错误属于Emscripten缓存机制在多线程编译场景下的锁冲突问题:

  • 启用-sUSE_PTHREADS=1后,Emscripten会并行编译SDL2、SDL_image等依赖项,但缓存锁的嵌套处理逻辑存在缺陷,导致子进程尝试获取已被父进程持有的libSDL2.a缓存锁,触发断言失败。
  • CMake配置中重复在编译标志和链接标志里设置-sUSE_PTHREADS=1、-sUSE_SDL=2等参数,进一步加剧了编译流程中的资源竞争。

解决方法

1. 清理缓存并重建

先彻底清除Emscripten缓存,消除残留的锁状态:

emcc --clear-cache

删除CMake构建目录后重新生成配置并编译:

rm -rf build && mkdir build && cd build
cmake ..
make

2. 合并重复的编译参数

将依赖相关参数(如-sUSE_PTHREADS=1、-sUSE_SDL=2)仅放在编译标志中,链接标志不再重复设置,减少参数冲突:
修改后的CMake配置示例:

set(USE_FLAGS "-sUSE_ZLIB=1 -sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS=['png,jpg'] -O3 -g -sWASM_WORKERS -sUSE_PTHREADS=1" CACHE STRING "Compilation flags" FORCE)

set(LINKING_FLAGS "--preload-file ${ASSETS_PATH}/assets@/assets -sFULL_ES2 -sWASM=1 -sFETCH=1 -sEXIT_RUNTIME=1 -sALLOW_MEMORY_GROWTH=1 -sEXPORTED_FUNCTIONS=['_main','_photoTaken','_malloc','_setNotificationToken','_interceptPushNotification','stackSave','stackRestore','stackAlloc'] -sEXPORTED_RUNTIME_METHODS=[cwrap] -sFORCE_FILESYSTEM=1 -lidbfs.js -O3 -g -sAUDIO_WORKLET=1 -sWASM_WORKERS -sASYNCIFY -sASYNCIFY_STACK_SIZE=131072 -sWEBAUDIO_DEBUG=1 -sPTHREAD_POOL_SIZE=8 -sPROXY_TO_PTHREAD" CACHE STRING "Linking flags" FORCE)

3. 限制并行编译线程数

若上述方法无效,可强制减少CMake并行编译的线程数,降低缓存锁竞争概率:

make -j4  # 根据硬件配置调整线程数,比如4或2

4. 更新Emscripten到最新版本

该锁冲突问题可能是旧版本Emscripten的已知bug,更新到最新稳定版可修复:

cd emsdk
./emsdk update
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh

内容的提问来源于stack exchange,提问作者oregu1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:24:50