2017-10-25 8 views
1

AFAIK Node.js非同期タスクがlibuvにディスパッチされ、libuvにはスレッドプールがあり、デフォルトでプールには4つのスレッドがあります。 私は以下のコードをテスト:私は3タスクを同時に実行しますlibuvに送ると思うし、出力A/B/Cがほぼ同時に印刷する必要がありますが、なぜNode.js libuvスレッドプールの実行が同時に行われないのですか?

setImmediate(() => { 
    sleep(1000 * 3); 
    console.log('a'); 
}); 

setImmediate(() => { 
    sleep(1000 * 3); 
    console.log('b'); 
}); 

setImmediate(() => { 
    sleep(1000 * 3); 
    console.log('c'); 
}); 

function sleep(time) { 
    let start = new Date().getTime(); 
    while (new Date().getTime() - start < time) { 
    } 
} 

を実際には、3つの出力3秒ごとに表示されます。 どこが間違っていますか?ありがとう。 4つのスレッドは デフォルトプールにある、

答えて

1

私の知る限りNode.jsの非同期タスクは フードの下libuvにディスパッチされ、そしてlibuvは、スレッドプールを有しています。私は以下のコードをテストします:

しかし、全く間違っていませんが、どちらも正しくありません。スレッドプールはデフォルトでは使用されません。スレッドプールは、ファイルIOやDNSルックアップなどのIOタスクを同期させるためにのみ使用されます。これらのタスクのコールバックはJSスレッドに再びエンキューされます。

Libuvタイマーは通常のタイマーキューを使用します。簡単に言えば、新しいタイマーを作成するたびに、ライブラリは待機する必要のある最小時間を確認し、待機してからすべてのタイマーを反復して更新し、満了したタイマーのコールバックを起動します。それはステップ1に戻り、それが待たなければならない最小時間をチェックする。

何百万ものタイマーを作成でき、それらはすべて同じスレッドを使用できます。それらは実行するためにスレッドプールを必要としません。

プログラムは正常に動作します。コールバックはメインのJSスレッドにすぐにエンキューされ、それぞれの値は3秒間待機して値を出力してから移動します。この場合、開始するタイマーさえありません。私はかなり確信していますsetImmediateは単にイベントループキューの最後にタスクをエンキューします。

関連する問題