1

確認する必要のあるファイル名の配列がたくさんありますが、ネットワーククライアントにも応答する必要があります。最も簡単な方法は、次のことを実行することです。

    for(var i = 0; i <array.length; i ++){
        fs.readFile(array [i]、function(err、data){...});
    }

、ただし、配列は任意の長さ、たとえば100000にすることができるため、一度に100000の読み取りを実行することはお勧めできません。一方、fs.readFileSync()の実行には時間がかかりすぎる可能性があります。また、次のように、コールバックで次のfs.readFile()を起動します。

    var Idx = 0;
    関数checkFile(){
       fs.readFile(array [Idx]、function(err、data){
          Idx ++;
          if(Idx <array.length){
             checkFile();
          } そうしないと {
             Idx = 0;
             setTimeout(checkFile、10000); //1秒でファイルのチェックを開始します
          }
       });
    }

array []はネットワーククライアントによって絶えず更新されるため(一部のアイテムが削除されたり、新しく追加されたりするなど)、これも最適なオプションではありません。

node.jsでそのようなタスクを実行するための最良の方法は何ですか?

4

1 に答える 1

3

最初の解決策 ( ) に固執する必要がありますfs.readFile。ファイル I/O の場合、node.js はスレッド プールを使用します。その理由は、ほとんどの UNIX カーネルがファイル システム用の効率的な非同期 API を提供していないためです。10,000 の読み取りを同時に開始したとしても、実際に実行される読み取りはごくわずかで、残りはキューで待機します。

この回答をより興味深いものにするために、ノードのコードをもう一度参照して、変更がないことを確認しました。

簡単に言うと、ファイル I/O はブロッキング システム コールを使用し、最大 4 つの同時スレッドを持つスレッド プールによって行われます。

重要なコードはlibeioにあり、これはlibuvによって抽象化されています。すべての I/O コードは、要求をキューに入れるマクロによってラップされます。例えば:

eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel)
{
  REQ (EIO_READ); req->int1 = fd; req->offs = offset; req->size = length; req->ptr2 = buf; SEND;
}

REQリクエストを準備してSENDキューに入れます。最終的にはetp_maybe_start_thread:

static unsigned int started, idle, wanted = 4;

(...)

static void
etp_maybe_start_thread (void)
{
  if (ecb_expect_true (etp_nthreads () >= wanted))
    return;
(...)

キューは、リクエストを処理するために 4 つのスレッドを実行し続けます。読み取りリクエストが最終的に実行されると、eio は単にreadunistd.h のブロックを使用します。

case EIO_READ:      ALLOC (req->size);
                          req->result = req->offs >= 0
                                      ? pread     (req->int1, req->ptr2, req->size, req->offs)
                                      : read      (req->int1, req->ptr2, req->size); break;
于 2012-08-09T11:19:30.177 に答える