2013-04-24 22 views
2

今天,當我嘗試實現在NodeJ中使用異步/同步I/O方法的示例時,我遇到了一個奇怪的問題。當我試圖用ab發送請求,我在異步方法來獲取此錯誤:異步文件讀取中的EMFILE錯誤

{ [Error: EMFILE, open 'sample.txt'] errno: 20, code: 'EMFILE', path: 'sample.txt' } 

但在同步模式相同的功能運作良好,沒有任何錯誤。

這是我運行測試ab命令:

ab -n 10000 -c 1000 -vhr http://localhost:8080/ 

這裏是我的兩個代碼:

異步

http.createServer(function (req, res) { 
    fs.readFile('sample.txt', function (err, data) { 
    if(err) { 
     res.writeHead(500, {'Content-Type': 'text/plain'}); 
     res.end(); 
     console.log(err); 
    } else { 
     res.writeHead(200, {'Content-Type': 'text/plain'}); 
     res.end(data); 
    } 
    }); 
}).listen(8080, '127.0.0.1'); 

同步

http.createServer(function (req, res) { 
    var fileOutput = fs.readFileSync('sample.txt').toString(); 
    if(!fileOutput) { 
     res.writeHead(500, {'Content-Type': 'text/plain'}); 
     res.end('Error in reading the file.'); 
    } else { 
    res.writeHead(200, {'Content-Type': 'text/plain'}); 
     res.end(fileOutput); 
    } 
}).listen(8081, '127.0.0.1'); 

這是怎麼回事?使用異步方法有什麼問題嗎?

回答

3

在這兩個你做到以下幾點:

1 - 打開文件。 2 - 讀取文件。 3 - 關閉文件。 4 - 發送回覆。

但是,同步時,您總是在一個語句中執行以下操作:(1-2-3)。它們是原子的。您可能在發送文件之前打開了許多文件,但您一直打開它並關閉它。然而,在異步方面,它們不是原子的,在給定的時間內它們中的任何一個都可以開始。因此,在異步時,它更可能收到請求,打開文件,但在發送它們之前,您實際上打開了更多文件。不久,同步,你開讀 - 關閉 - 發送數據,在異步你打開 - 公開 - 公開 - 公開 - 公開 - 公開 - 公開 - 公開 - 發送 - 打開(這些事件順序取決於到達時間數據和磁盤讀取速度)。

+0

很好,看起來不錯的解決方案。當我使用'fs.readFile'時,如何關閉鏈接? – 2013-04-25 12:25:56

+0

您不能,您需要限制連接數或更好地增加您使用的系統的打開文件限制。 – Mustafa 2013-04-25 17:01:49