Linux 为什么 STRACE 显示 EAGAIN(资源暂时不可用)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17666145/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:16:15  来源:igfitidea点击:

Why STRACE shows EAGAIN (Resource temporarily unavailable)

linuxtcpstrace

提问by Avinash

Following is the sequence I am getting

以下是我得到的序列

socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 7

    setsockopt(7, SOL_TCP, TCP_NODELAY, [1], 4) = 0
    setsockopt(7, SOL_SOCKET, SO_SNDBUF, [32120], 4) = 0
    getsockopt(7, SOL_SOCKET, SO_SNDBUF, [30064835312], [4]) = 0
    setsockopt(7, SOL_SOCKET, SO_SNDBUF, [64240], 4) = 0
    getsockopt(7, SOL_SOCKET, SO_SNDBUF, [30064899552], [4]) = 0
    stat("/etc/localtime", {st_dev=makedev(8, 1), st_ino=229001, st_mode=S_IFREG|0644, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=265, st_atime=2013/07/15-06:30:03, st_mtime=2012/06/25-23:46:43, st_ctime=2012/06/25-23:46:43}) = 0
    write(1, "[info 2013/07/16 05:53:24.622210"..., 114) = 114
    setsockopt(7, SOL_SOCKET, SO_RCVBUF, [32120], 4) = 0
    getsockopt(7, SOL_SOCKET, SO_RCVBUF, [30064835312], [4]) = 0
    setsockopt(7, SOL_SOCKET, SO_RCVBUF, [64240], 4) = 0
    getsockopt(7, SOL_SOCKET, SO_RCVBUF, [30064899552], [4]) = 0
    fcntl(7, F_GETFL)                       = 0x2 (flags O_RDWR)
    fcntl(7, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
    rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x33b3632920}, {SIG_DFL, [], 0}, 8) = 0
    fcntl(7, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
    fcntl(7, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
    connect(7, {sa_family=AF_INET, sin_port=htons(50505), sin_addr=inet_addr("1.2.3.4")}, 16) = -1 EINPROGRESS (Operation now in progress)
    poll([{fd=7, events=POLLIN|POLLOUT}], 1, 59000) = 1 ([{fd=7, revents=POLLOUT}])
    fcntl(7, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
    fcntl(7, F_SETFL, O_RDWR)               = 0
    getsockname(7, {sa_family=AF_INET, sin_port=htons(33220), sin_addr=inet_addr("10.112.204.215")}, [16]) = 0
    fcntl(7, F_GETFL)                       = 0x2 (flags O_RDWR)
    fcntl(7, F_GETFL)                       = 0x2 (flags O_RDWR)
    fcntl(7, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
    write(7, "d;7707&W\\np47##代码####代码####代码##W##代码##\rpnq-gst-"..., 103) = 103
    fcntl(7, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
    fcntl(7, F_SETFL, O_RDWR)               = 0
    fcntl(7, F_GETFL)                       = 0x2 (flags O_RDWR)
    fcntl(7, F_GETFL)                       = 0x2 (flags O_RDWR)
    fcntl(7, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
    read(7, 0x9d9f90, 1)                    = -1 EAGAIN (Resource temporarily unavailable)

Why this read is getting called, I assume that pollshould wake up only when there is data to read

为什么这个读取被调用,我认为poll只有在有数据要读取时才应该唤醒

采纳答案by Barmar

pollwoke up with revents = POLLOUT, which means that the socket is ready to write, not ready to read. The code is apparently not checking this flag, and trying to read anyway.

poll用 唤醒revents = POLLOUT,这意味着套接字已准备好写入,未准备好读取。代码显然没有检查这个标志,并试图阅读。

This might be intentional. Even though polldidn't say the socket is ready to read, it might have become ready while it was writing. So it calls ready just in case something has shown up. If not, it will go back into pollto wait again. This allows it to process incoming data more quickly, since it can get it in one call rather than two.

这可能是故意的。即使poll没有说套接字已准备好读取,它也可能在写入时准备就绪。所以它会调用 ready 以防万一出现了问题。如果没有,它会重新进入poll等待。这使它能够更快地处理传入的数据,因为它可以通过一次调用而不是两次调用来获取它。