feat: 增加MaaContextRunRecognitionList并行识别#1348
Conversation
There was a problem hiding this comment.
Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:
- 在
TemplateResMgr::get_image中,互斥锁在整个惰性加载流程中都被持有,包括cv::imread,这可能会引入不必要的锁竞争;建议拆分临界区,使映射查找/更新在锁保护下进行,而潜在耗时的磁盘 I/O 则在锁外完成。 - 对于
OCRResMgr::clear和ONNXResMgr::clear,你现在只用models_mutex_保护模型 map,而没有保护roots_;如果识别线程中也会访问roots_,建议在访问roots_时也持有同一把互斥锁,以保持一致并避免潜在的数据竞争。
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `TemplateResMgr::get_image`, the mutex is held across the entire lazy-load path including `cv::imread`, which may introduce unnecessary contention; consider splitting the critical section so that the map lookup/update is protected but the potentially expensive disk I/O happens outside the lock.
- For `OCRResMgr::clear` and `ONNXResMgr::clear`, you now protect only the model maps with `models_mutex_` but not `roots_`; if `roots_` is also accessed from recognition threads, you may want to hold the same mutex while touching it for consistency and to avoid potential data races.
## Individual Comments
### Comment 1
<location path="source/MaaFramework/Resource/OCRResMgr.cpp" line_range="97-101" />
<code_context>
LogFunc;
roots_.clear();
+ std::lock_guard lock(models_mutex_);
deters_.clear();
recers_.clear();
ocrers_.clear();
</code_context>
<issue_to_address>
**issue (bug_risk):** `clear()` only guards model maps, not `roots_`, which can still race with concurrent access.
`roots_.clear()` runs without `models_mutex_`, while `deters_/recers_/ocrers_` are cleared under that lock. If any code holds `models_mutex_` and reads `roots_` (e.g., in lazy-load paths for deter/recer/ocrer), this creates a data race on `roots_`. Please either clear `roots_` under `models_mutex_` as well, or guarantee that `roots_` is only ever modified in a single-threaded context and never accessed concurrently with `clear()`.
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的代码审查。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- In
TemplateResMgr::get_image, the mutex is held across the entire lazy-load path includingcv::imread, which may introduce unnecessary contention; consider splitting the critical section so that the map lookup/update is protected but the potentially expensive disk I/O happens outside the lock. - For
OCRResMgr::clearandONNXResMgr::clear, you now protect only the model maps withmodels_mutex_but notroots_; ifroots_is also accessed from recognition threads, you may want to hold the same mutex while touching it for consistency and to avoid potential data races.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `TemplateResMgr::get_image`, the mutex is held across the entire lazy-load path including `cv::imread`, which may introduce unnecessary contention; consider splitting the critical section so that the map lookup/update is protected but the potentially expensive disk I/O happens outside the lock.
- For `OCRResMgr::clear` and `ONNXResMgr::clear`, you now protect only the model maps with `models_mutex_` but not `roots_`; if `roots_` is also accessed from recognition threads, you may want to hold the same mutex while touching it for consistency and to avoid potential data races.
## Individual Comments
### Comment 1
<location path="source/MaaFramework/Resource/OCRResMgr.cpp" line_range="97-101" />
<code_context>
LogFunc;
roots_.clear();
+ std::lock_guard lock(models_mutex_);
deters_.clear();
recers_.clear();
ocrers_.clear();
</code_context>
<issue_to_address>
**issue (bug_risk):** `clear()` only guards model maps, not `roots_`, which can still race with concurrent access.
`roots_.clear()` runs without `models_mutex_`, while `deters_/recers_/ocrers_` are cleared under that lock. If any code holds `models_mutex_` and reads `roots_` (e.g., in lazy-load paths for deter/recer/ocrer), this creates a data race on `roots_`. Please either clear `roots_` under `models_mutex_` as well, or guarantee that `roots_` is only ever modified in a single-threaded context and never accessed concurrently with `clear()`.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| roots_.clear(); | ||
| std::lock_guard lock(models_mutex_); | ||
| deters_.clear(); | ||
| recers_.clear(); | ||
| ocrers_.clear(); |
There was a problem hiding this comment.
issue (bug_risk): clear() 只对模型 map 加锁保护,而没有保护 roots_,这仍然可能与并发访问产生竞争。
roots_.clear() 在没有持有 models_mutex_ 的情况下执行,而 deters_/recers_/ocrers_ 是在这把锁下被清理的。如果有任何代码在持有 models_mutex_ 的同时读取 roots_(例如在 deter/recer/ocrer 的惰性加载路径中),就会在 roots_ 上产生数据竞争。请要么也在持有 models_mutex_ 的情况下清理 roots_,要么保证 roots_ 只会在单线程上下文中被修改,并且不会在与 clear() 并发的情况下被访问。
Original comment in English
issue (bug_risk): clear() only guards model maps, not roots_, which can still race with concurrent access.
roots_.clear() runs without models_mutex_, while deters_/recers_/ocrers_ are cleared under that lock. If any code holds models_mutex_ and reads roots_ (e.g., in lazy-load paths for deter/recer/ocrer), this creates a data race on roots_. Please either clear roots_ under models_mutex_ as well, or guarantee that roots_ is only ever modified in a single-threaded context and never accessed concurrently with clear().
|
好丑啊,不太行。 最好想个法子从 pipeline 的角度支持 |
ok |
背景:maaend实时任务用,ipc只能串行执行,因此加一个RecognitionList方法,全部识别完成后返回结果。
内部实现:
普通节点并行识别,custom节点串行执行
返回值:博爱成功或失败
输出:MaaRecoId* 识别结果数组,长度根据传入entries_json 个数决定
opus4.8
Summary by Sourcery
添加了一个新的 API 和 IPC 路径,用于在单帧图像上并行运行针对多个条目的识别,并返回首个命中的索引;同时使模型/模板资源管理器在并发识别场景下实现线程安全。
New Features:
Context::run_recognition_list以及对应的 C APIMaaContextRunRecognitionList,用于在同一张图像上识别多个条目,并返回优先级最高的命中索引。MaaContextRunRecognitionList。Enhancements:
Documentation:
MaaContextRunRecognitionListAPI 的行为、参数和返回值。Original summary in English
Summary by Sourcery
Add a new API and IPC path to run recognition on a list of entries against a single frame in parallel, returning the first hit index, and make model/template resource managers thread-safe for concurrent recognition.
New Features:
Enhancements:
Documentation: