2017-11-20 13 views
1

tutorial for libuvによれば、後でuv_writeを呼び出すと、別の書き込みをブロックする書き込みが発生してはなりません(別のスレッドで発生するはずです)。
しかし、私はstraceの下のサンプルコードを実行しましたが、そうではないようです。 uv_fs_writeを使って同様の例を実行すると、書き込みの呼び出しは別のスレッドで行われ、ブロックされないことがわかります。uv_writeは実際には非同期ですか?

期待される振る舞いがuv_writeのものであることを誰かが説明し、基礎となるストリームがファイルハンドルであるときにuv_fs_writeと異なるはずですか?

cat Makefile | strace ./uvtee/uvtee ~/out.txt 

open("/home/james/out.txt", O_RDWR|O_CREAT|O_CLOEXEC, 0644) = 11 
ioctl(11, FIONBIO, [1])     = 0 
epoll_ctl(6, EPOLL_CTL_ADD, 7, {EPOLLIN, {u32=7, u64=7}}) = 0 
epoll_ctl(6, EPOLL_CTL_ADD, 9, {EPOLLIN, {u32=9, u64=9}}) = 0 
epoll_ctl(6, EPOLL_CTL_ADD, 0, {EPOLLIN, {u32=0, u64=0}}) = 0 
epoll_wait(6, [{EPOLLIN|EPOLLHUP, {u32=0, u64=0}}], 1024, -1) = 1 
brk(0xb3e000)       = 0xb3e000 
read(0, "examples=\\\n\thelloworld\\\n\tidle-ba"..., 65536) = 1965 
write(1, "examples=\\\n\thelloworld\\\n\tidle-ba"..., 1965) = 1965 
write(11, "examples=\\\n\thelloworld\\\n\tidle-ba"..., 1965) = 1965 

フルコードはhereです。

+0

私はそれを修正しました。うまくいけば、今は少しはっきりしています。 – js7222

+0

リンク先の例が適切な例ですか?ファイルをパイプのように扱うようですが、通常のファイルを参照するファイル記述子のuv_pipe_open()を呼び出します。これは質問のポイントをバイパスしているようです。 – nos

+0

申し訳ありません。この例では、パイプを使用してファイルハンドルを抽象化しています。パイプを使ってファイルを処理し、uv_writeを呼び出すのがuv_fs_writeを使うのとは異なる振る舞いをすることを期待しているかどうか本当に知りたかったのですか? uv_write_writeはスレッドが書き込みのために生成されているのに対し、uv_writeは同じスレッドに書き込みを行うためのシーケンシャルな呼び出しを行います。 – js7222

答えて

0

fs操作はスレッドプール上で実行されます。これは、ファイルのノンブロッキングIOを行うための優れた移植可能な方法がないためです。スレッドプールを使用するため、書き込み操作は並列に実行することができます。そのため、uv_fs_writeはオフセット・パラメータを取るため、複数のスレーブが互いの上に踏み込むことなく書き込むことができます。

ここで注目すべき例外は、MacOSで、グローバルロックが使用されてuv_fs_write操作がシリアル化されます。

今、ネットワークIOはまったく異なります。我々は、(あなたが知っているように)イベントループを使用して、書き込み操作がキューに入れられているので、送信された順序で書き込みが行われます。

関連する問題