2026年了,怎么在 Hydro 配置通信题?
测试功能,可能还有大量问题。
2026年了,怎么在 Hydro 配置通信题?
我们注意到 Hydro 题目中有这个选项:

好的怎么用呢?
我们发现,没有任何文档指出这个类型该怎么配置。
但在 Hydro 的 Github 仓库上,我们找到了一份代码:
import { NormalizedCase, STATUS } from '@hydrooj/common';
import { runFlow } from '../flow';
import { Parameter, runPiped } from '../sandbox';
import signals from '../signals';
import { Context, ContextSubTask } from './interface';
function judgeCase(c: NormalizedCase) {
return async (ctx: Context, ctxSubtask: ContextSubTask) => {
const { address_space_limit, process_limit } = ctx.session.getLang(ctx.lang);
let managerArgs = '';
const execute: Parameter[] = [{
execute: ctx.executeManager.execute,
stdin: c.input ? { src: c.input } : { content: '' },
copyIn: ctx.executeManager.copyIn,
time: c.time * 2,
memory: c.memory * 2,
env: { ...ctx.env, HYDRO_TESTCASE: c.id.toString() },
}];
const pipeMapping = [];
for (let i = 0; i < ctx.config.num_processes; i++) {
managerArgs += ` /proc/self/fd/${i * 2 + 3} /proc/self/fd/${i * 2 + 4}`;
execute.push({
execute: `${ctx.executeUser.execute} ${i}`,
copyIn: ctx.executeUser.copyIn,
time: c.time,
memory: c.memory,
addressSpaceLimit: address_space_limit,
processLimit: process_limit,
});
pipeMapping.push({
name: `sol2mgr[${i}]`,
in: { index: i + 1, fd: 1 },
out: { index: 0, fd: i * 2 + 3 },
});
pipeMapping.push({
name: `mgr2sol[${i}]`,
in: { index: 0, fd: i * 2 + 4 },
out: { index: i + 1, fd: 0 },
});
}
execute[0].execute += managerArgs;
const res = await runPiped(execute, pipeMapping);
const resManager = res[0];
let time = 0;
let memory = 0;
let score = 0;
let status = STATUS.STATUS_ACCEPTED;
let message: any;
for (let i = 0; i < ctx.config.num_processes; i++) {
const result = res[i + 1];
time += result.time;
memory = Math.max(memory, result.memory);
if (result.time > c.time) status = STATUS.STATUS_TIME_LIMIT_EXCEEDED;
else if (result.memory > c.memory * 1024) status = STATUS.STATUS_MEMORY_LIMIT_EXCEEDED;
else if ((result.code && result.code !== 13 /* Broken Pipe */) || (result.code === 13 && !resManager.code)) {
status = STATUS.STATUS_RUNTIME_ERROR;
if (ctx.config.detail === 'full') {
if (result.code < 32 && result.signalled) message = signals[result.code];
else message = { message: 'Your program returned {0}.', params: [result.code] };
}
}
}
if (status === STATUS.STATUS_ACCEPTED) {
score = Math.floor(c.score * (+resManager.stdout || 0));
status = score === c.score ? STATUS.STATUS_ACCEPTED : STATUS.STATUS_WRONG_ANSWER;
message = resManager.stderr;
if (resManager.code) message += ` (Manager exited with code ${resManager.code})`;
}
return {
id: c.id,
subtaskId: ctxSubtask.subtask.id,
status,
score,
time,
memory,
message,
};
};
}
export const judge = async (ctx: Context) => await runFlow(ctx, {
compile: async () => {
[ctx.executeUser, ctx.executeManager] = await Promise.all([
ctx.compile(ctx.lang, ctx.code),
ctx.compileLocalFile('manager', ctx.config.manager),
]);
},
judgeCase,
});
这便是唯一有关通信题配置的了。
当然很可能看不懂(我也看不懂),但在使用 AI 工具分析后,就知道 Hydro 如何评测通信题了:
- 你需要实现一个
manager,功能是管理通信和评分。 - Hydro 会将选手代码在
num_processes个进程里独立运行,同时创建num_processes*2个管道,第 \(i\) 个进程的输入被重定向到管道 \(2i+4\),输出被重定向到是 \(2i+3\)。 Manager可以使用管道与进程 IO 通信,最后输出 \([0,1]\) 间的实数表示分数,stderr将输出评分信息,stdin读入数据。
接下来便有思路了。

浙公网安备 33010602011771号