2013-04-24 24 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