From e175a4d2ed02d69a7d4b1ab4ec1e51a81cef2141 Mon Sep 17 00:00:00 2001 From: heerim hong Date: Sun, 10 Nov 2024 16:15:42 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9E=90=EB=B0=94=EC=8A=A4=ED=81=AC=EB=A6=BD?= =?UTF-8?q?=ED=8A=B8=20:=20Mutex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- .../concurrent/my-mutex.js" | 63 +++++++++++++++++++ .../concurrent/recursive-async.js" | 17 +++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 "\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270/concurrent/my-mutex.js" create mode 100644 "\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270/concurrent/recursive-async.js" diff --git a/.gitignore b/.gitignore index 54bae13..22eafaf 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -/**/tempCodeRunnerFile.js \ No newline at end of file +/**/tempCodeRunnerFile.js +/**/node_modules \ No newline at end of file diff --git "a/\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270/concurrent/my-mutex.js" "b/\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270/concurrent/my-mutex.js" new file mode 100644 index 0000000..7cc1508 --- /dev/null +++ "b/\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270/concurrent/my-mutex.js" @@ -0,0 +1,63 @@ +/** + * Promise.all을 사용하는 경우, 한번에 모든 Promise를 처리하므로, mutex를 걸어준다. + * 혹은 forEach, map 대신 reduce를 사용하거나, for문 사용해도 가능하다. + */ + +class Mutex { + constructor() { + this._isLocked = false; + } + + lock() { + this._isLocked = true; + } + + unlock() { + this._isLocked = false; + } + + release() { + this.unlock(); + } + + async acquire(count = 0) { + if (count >= 10) throw new Error("Mutex lock count exceeded"); + + const isLocked = this._isLocked; + if (!isLocked) { + this.lock(); + return Promise.resolve(); + } else { + return new Promise((resolve) => { + setTimeout(() => { + this.acquire(count + 1).then(resolve); + }, 100); + }); + } + } +} + +let sum = 0; +const mutex = new Mutex(); + +const wait = () => + new Promise((resolve) => setTimeout(resolve, Math.random() * 50)); + +async function add(order) { + await mutex.acquire(); + console.log(`[${order}] start`); + + await wait(); // async logic + sum += 1; + + console.log(`[${order}] end`); + mutex.release(); +} + +async function main() { + console.log("start"); + await Promise.all([add(1), add(2), add(3)]); + console.log("end"); +} + +main(); diff --git "a/\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270/concurrent/recursive-async.js" "b/\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270/concurrent/recursive-async.js" new file mode 100644 index 0000000..47f9a4c --- /dev/null +++ "b/\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270/concurrent/recursive-async.js" @@ -0,0 +1,17 @@ +async function recursiveAsync(count = 0) { + console.log("count is", count); + return new Promise((resolve) => + setTimeout(async () => { + await recursiveAsync(count + 1); + resolve(); + }, 500) + ); +} + +async function main() { + console.log("start"); + await recursiveAsync(); + console.log("end"); +} + +main();