訂判斷及所需輸入
受控 A、B 兩執行緒佔滿題內兩名額,C 在等。只收到取消要求而未終止,A 仍活、C 未跑;兩路都沿同一名額門檻。更正等 A 終止,移除佔位,再真正開 C,取得 ready。
| 情況 | 輸入 JSON |
|---|---|
| 原例測試 | {"capacity":2,"cancel":"A"} |
跑所附比較
核對看終止後 A.threadId 及新執行緒回覆,不只看排隊計數;之後清理其餘工作。只屬本地名額機制,不是供應商吞吐保證。
| 路徑 | 輸出 JSON |
|---|---|
| 錯誤路徑 | {"cancelledWorkerExited":false,"thirdStarted":false,"activeIds":["A","B"]} |
| 所需路徑 | {"cancelledWorkerExited":true,"thirdStarted":true,"activeIds":["B","C"]} |
import assert from 'node:assert/strict';
import {Worker} from 'node:worker_threads';
const run=async function run(i,corrected=true){
if(!['A'].includes(i.cancel)||![1,2].includes(i.capacity))return {held:true};const active=new Map();const workers=[];
const start=async id=>{assert(active.size<i.capacity);const w=new Worker('const {parentPort}=require("node:worker_threads");parentPort.postMessage("ready");setInterval(()=>{},1000);',{eval:true});workers.push(w);active.set(id,w);await new Promise(resolve=>w.once('message',resolve));};
try{await start('A');if(i.capacity===2)await start('B');const original=active.get('A');let thirdStarted=false;
if(corrected){await original.terminate();active.delete('A');}
if(active.size<i.capacity){await start('C');thirdStarted=true;}
return {cancelledWorkerExited:original.threadId===-1,thirdStarted,activeIds:[...active.keys()]};
}finally{await Promise.all(workers.filter(w=>w.threadId!==-1).map(w=>w.terminate()));}
};
const cases=[{"input":{"capacity":2,"cancel":"A"},"corrected":false,"expected":{"cancelledWorkerExited":false,"thirdStarted":false,"activeIds":["A","B"]}},{"input":{"capacity":2,"cancel":"A"},"corrected":true,"expected":{"cancelledWorkerExited":true,"thirdStarted":true,"activeIds":["B","C"]}},{"input":{"capacity":1,"cancel":"A"},"corrected":true,"expected":{"cancelledWorkerExited":true,"thirdStarted":true,"activeIds":["C"]}},{"input":{"capacity":2,"cancel":null},"corrected":true,"expected":{"held":true}}];
for(const test of cases){const actual=await run(test.input,test.corrected);assert.deepEqual(actual,test.expected);console.log(actual);}
按邊界依據作判斷
只有一名額時,A 先退出,C 才獨佔該位;取消對象欠缺,開工作前先停。
- 核真正已佔位執行緒
- 等被取消者退出
- 啟動並核待跑者
取消標記未證明執行資源已釋出。
| 條件 | 輸入 JSON | 預期輸出 JSON |
|---|---|---|
| 只有一個執行名額 | {"capacity":1,"cancel":"A"} | {"cancelledWorkerExited":true,"thirdStarted":true,"activeIds":["C"]} |
| 取消對象未明 | {"capacity":2,"cancel":null} | {"held":true} |
原例更正路徑,甚麼依據才容 C 跑?
查看參考答案
A 真退出,釋出的名額收 C,且 C 已報 ready。活躍編號是 B、C,不是 A、B。