在編程中,信號(hào)量(Semaphore)是一種非常有用的概念,用于控制并發(fā)訪問(wèn)共享資源。
在JavaScript中,我們可以使用信號(hào)量來(lái)保證任意時(shí)刻只有一段代碼可以訪問(wèn)特定資源。下面我們來(lái)看一些實(shí)際例子。
// 使用信號(hào)量來(lái)控制并發(fā)請(qǐng)求 const MAX_REQUESTS = 3; // 最大并發(fā)請(qǐng)求數(shù) let currentRequests = 0; // 當(dāng)前并發(fā)請(qǐng)求數(shù) async function makeRequest() { // 如果當(dāng)前并發(fā)請(qǐng)求數(shù)已經(jīng)達(dá)到上限,則等待其他請(qǐng)求返回 while (currentRequests >= MAX_REQUESTS) { await new Promise(resolve => setTimeout(resolve, 100)); } // 增加當(dāng)前并發(fā)請(qǐng)求數(shù) currentRequests++; // 發(fā)送請(qǐng)求... // 請(qǐng)求完成后減少當(dāng)前并發(fā)請(qǐng)求數(shù) currentRequests--; }
在上面的代碼中,我們使用一個(gè)全局變量來(lái)記錄當(dāng)前并發(fā)請(qǐng)求數(shù),然后在發(fā)送請(qǐng)求前先檢查當(dāng)前并發(fā)請(qǐng)求數(shù)是否已經(jīng)達(dá)到最大值。如果是,我們就等待一段時(shí)間,再檢查一次。如果當(dāng)前并發(fā)請(qǐng)求數(shù)仍然達(dá)到最大值,我們就繼續(xù)等待。
只有當(dāng)某個(gè)請(qǐng)求完成后,當(dāng)前并發(fā)請(qǐng)求數(shù)才會(huì)減少,這樣其他請(qǐng)求才有機(jī)會(huì)繼續(xù)執(zhí)行。
// 使用信號(hào)量來(lái)控制文件讀寫 const fs = require('fs'); const SEMAPHORE = 1; // 同時(shí)只允許一個(gè)文件讀寫 class File { constructor(path) { this.path = path; this.isLocked = false; } read() { return new Promise((resolve, reject) => { // 如果文件被鎖定,則等待 const lockInterval = setInterval(() => { if (!this.isLocked) { clearInterval(lockInterval); // 鎖定文件 this.isLocked = true; // 讀取文件... fs.readFile(this.path, (err, data) => { // 解鎖文件 this.isLocked = false; if (err) { reject(err); } else { resolve(data); } }); } }, 100); }); } write(data) { return new Promise((resolve, reject) => { // 如果文件被鎖定,則等待 const lockInterval = setInterval(() => { if (!this.isLocked) { clearInterval(lockInterval); // 鎖定文件 this.isLocked = true; // 寫入文件... fs.writeFile(this.path, data, err => { // 解鎖文件 this.isLocked = false; if (err) { reject(err); } else { resolve(); } }); } }, 100); }); } } const file = new File('example.txt'); (async function() { const data = await file.read(); console.log(data.toString()); await file.write('Hello, world!'); })();
在上面的代碼中,我們定義了一個(gè)File類來(lái)讀寫文件。File類中的read和write方法都使用了信號(hào)量來(lái)鎖定文件,這樣我們就可以保證任意時(shí)刻只有一個(gè)讀寫操作可以對(duì)文件進(jìn)行操作。
當(dāng)我們讀取文件時(shí),首先檢查文件是否被鎖定。如果是,我們就等待一段時(shí)間,再檢查一次。只有當(dāng)文件沒(méi)有被鎖定時(shí),我們才可以對(duì)其進(jìn)行讀取操作。寫入操作的實(shí)現(xiàn)方式與之類似。
在實(shí)際編程中,信號(hào)量是一種非常有用的工具,可以幫助我們管理并發(fā)訪問(wèn)共享資源,避免出現(xiàn)競(jìng)態(tài)條件和死鎖等問(wèn)題。