【发布时间】:2017-11-20 22:01:05
【问题描述】:
根据tutorial for libuv,对uv_write 的后续调用不应导致一个写入阻塞另一个写入(我的理解是它们应该发生在不同的线程上)。
但是我已经在strace 下运行了示例代码,但似乎情况并非如此。使用uv_fs_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找到。
【问题讨论】:
-
我已经修好了。希望现在更清楚一点。
-
您确定您链接到的示例是相关示例吗?似乎将文件视为管道,它在引用常规文件的文件描述符上调用 uv_pipe_open() - 这似乎绕过了您的问题。
-
对不起,示例使用管道来抽象文件句柄。我真正想知道的是,它是否期望使用管道处理文件并调用 uv_write 与使用 uv_fs_write 有不同的行为?似乎在 uv_fs_write 中为写入生成了一个线程,而 uv_write 在同一线程上进行了顺序调用。
-
如果你从表面上看文档,它说对于某些类型(例如管道),写入不是在单独的线程中完成的(因为管道可以集成到事件循环中),而对于文件/使用 uv_fs_write 时,操作发生在单独的线程中。即是的,您正在看到预期的行为。也就是说,libuv 的设计可能不会假设您应该对 libuv 撒谎并将引用文件的描述符与管道连接 - uv_pipe_open() 的文档甚至说“但它要求它代表一个有效的管道。”。所以没有保证的行为。
标签: c linux asynchronous strace libuv