我可以在 gevent 应用程序的 strace 输出中 grep 什么来测试它是否正在使用阻塞网络 IO?
What could I grep for in strace output from a gevent app to test whether it's using blocking network IO?
我有一个小型 gevent 服务器,它也是其他 api 的 http 客户端。我使用的一个库有 httplib 作为依赖项。
我愿意monkey.patch_all。没有磁盘IO,只有网络。
我对我的系统调用生疏了,但我想知道是否有一种简单的方法来测试是否正在使用 strace 进行阻塞调用。
我知道如何使用 strace,但不确定我可能会用 grep 做什么。
这行得通吗?
谢谢
我自己做了一些实验,认为我至少找到了部分答案。
我制作了一个一次性网络应用程序,它只休眠 5 秒然后响应 'hello'。
然后我写了两个客户端。一个使用 python 请求,另一个使用 grequests(异步请求模块)。
第一个客户:
import requests
resp = requests.get('http://localhost:1234')
第二个客户:
from gevent import monkey; monkey.patch_all()
import grequests
req = grequests.get('http://localhost:1234')
resp = grequests.map([req])[0]
我运行这些是:
strace -T -f -s1000 python blocking_io.py &> out
在(预期的)阻塞版本的输出中,我得到:
sendto(3, "GET / HTTP/1.1\r\nHost: localhost:1234\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.9.1\r\n\r\n", 144, 0, NULL, 0) = 144 <0.000022>
fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) <0.000008>
fcntl(3, F_SETFL, O_RDWR) = 0 <0.000007>
recvfrom(3, "HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 12\r\n", 8192, 0, NULL, NULL) = 77 <5.009440>
recvfrom(3, "Server: Werkzeug/0.11.5 Python/2.7.10\r\nDate: Tue, 05 Apr 2016 22:28:38 GMT\r\n\r\nHello World!", 8192, 0, NULL, NULL) = 90 <0.000067>
close(3) = 0 <0.000175>
请注意第一个 recvfrom
行末尾的 5 秒等待时间。
然后我为异步版本做了:
[pid 24359] sendto(5, "GET / HTTP/1.1\r\nHost: localhost:1234\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.9.1\r\n\r\n", 144, 0, NULL, 0) = 144 <0.000023>
[pid 24359] fcntl(5, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK) <0.000008>
[pid 24359] fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK) = 0 <0.000008>
[pid 24359] recvfrom(5, 0x2481624, 8192, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable) <0.000009>
[pid 24359] epoll_ctl(3, EPOLL_CTL_MOD, 5, {EPOLLIN, {u32=5, u64=8589934597}}) = 0 <0.000008>
[pid 24359] epoll_wait(3, {{EPOLLIN, {u32=5, u64=8589934597}}}, 64, 59743) = 1 <5.009130>
[pid 24359] recvfrom(5, "HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 12\r\nServer: Werkzeug/0.11.5 Python/2.7.10\r\nDate: Tue, 05 Apr 2016 22:29:50 GMT\r\n\r\nHello World!", 8192, 0, NULL, NULL) = 167 <0.000114>
[pid 24359] close(5) = 0 <0.000185>
在这种情况下,5 秒用于执行 epoll_wait
。
此外,阻塞版本
fcntl(3, F_SETFL, O_RDWR)
异步版本
fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK)
我有一个小型 gevent 服务器,它也是其他 api 的 http 客户端。我使用的一个库有 httplib 作为依赖项。
我愿意monkey.patch_all。没有磁盘IO,只有网络。
我对我的系统调用生疏了,但我想知道是否有一种简单的方法来测试是否正在使用 strace 进行阻塞调用。
我知道如何使用 strace,但不确定我可能会用 grep 做什么。
这行得通吗?
谢谢
我自己做了一些实验,认为我至少找到了部分答案。
我制作了一个一次性网络应用程序,它只休眠 5 秒然后响应 'hello'。
然后我写了两个客户端。一个使用 python 请求,另一个使用 grequests(异步请求模块)。
第一个客户:
import requests
resp = requests.get('http://localhost:1234')
第二个客户:
from gevent import monkey; monkey.patch_all()
import grequests
req = grequests.get('http://localhost:1234')
resp = grequests.map([req])[0]
我运行这些是:
strace -T -f -s1000 python blocking_io.py &> out
在(预期的)阻塞版本的输出中,我得到:
sendto(3, "GET / HTTP/1.1\r\nHost: localhost:1234\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.9.1\r\n\r\n", 144, 0, NULL, 0) = 144 <0.000022>
fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) <0.000008>
fcntl(3, F_SETFL, O_RDWR) = 0 <0.000007>
recvfrom(3, "HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 12\r\n", 8192, 0, NULL, NULL) = 77 <5.009440>
recvfrom(3, "Server: Werkzeug/0.11.5 Python/2.7.10\r\nDate: Tue, 05 Apr 2016 22:28:38 GMT\r\n\r\nHello World!", 8192, 0, NULL, NULL) = 90 <0.000067>
close(3) = 0 <0.000175>
请注意第一个 recvfrom
行末尾的 5 秒等待时间。
然后我为异步版本做了:
[pid 24359] sendto(5, "GET / HTTP/1.1\r\nHost: localhost:1234\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.9.1\r\n\r\n", 144, 0, NULL, 0) = 144 <0.000023>
[pid 24359] fcntl(5, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK) <0.000008>
[pid 24359] fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK) = 0 <0.000008>
[pid 24359] recvfrom(5, 0x2481624, 8192, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable) <0.000009>
[pid 24359] epoll_ctl(3, EPOLL_CTL_MOD, 5, {EPOLLIN, {u32=5, u64=8589934597}}) = 0 <0.000008>
[pid 24359] epoll_wait(3, {{EPOLLIN, {u32=5, u64=8589934597}}}, 64, 59743) = 1 <5.009130>
[pid 24359] recvfrom(5, "HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 12\r\nServer: Werkzeug/0.11.5 Python/2.7.10\r\nDate: Tue, 05 Apr 2016 22:29:50 GMT\r\n\r\nHello World!", 8192, 0, NULL, NULL) = 167 <0.000114>
[pid 24359] close(5) = 0 <0.000185>
在这种情况下,5 秒用于执行 epoll_wait
。
此外,阻塞版本
fcntl(3, F_SETFL, O_RDWR)
异步版本
fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK)