Асинхронный JavaScriptПараллельное программирование

Semaphore

Semaphore, как и mutex, является базовым кирпичиком параллельного праграммирования. Мы не разбираем параллельное программирование, эта задача — адаптация идеи для асинхронного программирования в JS.

Необходимо реализовать класс Semaphore с конструктором и двумя методами:

  • constructor — принимает capacity — количество задач, которые могут одновременно выполняться;
  • acquire — блокирует выполнение, пока ресурс не освободится, если лимит исчерпан;
  • release — разблокирует семафор и позволяет выполненить еще одну задачу.
class Semaphore { acquire(): Promise<void>; release(): void; }

Семафор обслуживает таски по принципу FIFO (First In, First Out — первый пришел, первый вышел).

Пример

const s = new Semaphore(2); async function task(ms) { await s.acquire(); try { await setTimeout(ms); console.log(ms, 'done'); console.timeLog('x'); } finally { s.release(); } } (async function () { console.time('x'); task(1000); task(400); task(800); task(1000); task(1000); task(1000); })();

На диаграме отмечены временные точки, когда мы попадаем в «критическую секцию» между acquire и release.

0 1000 2000 3000 |--------------|-------------|--------------| |-----|-----------|---------------| 400 1200 2200