De ce STRACE arată EAGAIN (Resursă temporar indisponibilă) (Programare, Linux, Tcp, Strace)

Avinash a intrebat.

Următoarea este secvența pe care o primesc

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, "d23;1773773303571&W1\4
p3143272Wrpnq-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)

De ce este apelată această citire, presupun că poll ar trebui să se trezească doar atunci când există date de citit

1 răspunsuri
Barmar

poll s-a trezit cu revents = POLLOUT, ceea ce înseamnă că socket-ul este gata să scrie, nu gata să citească. Se pare că codul nu verifică acest indicator și încearcă să citească oricum.

S-ar putea ca acest lucru să fie intenționat. Chiar dacă poll nu a spus că socket-ul este gata de citire, este posibil ca acesta să fi devenit gata în timp ce scria. Deci, solicită ready doar în cazul în care a apărut ceva. În caz contrar, se va întoarce la poll pentru a aștepta din nou. Acest lucru îi permite să proceseze mai rapid datele primite, deoarece le poate primi într-un singur apel, în loc de două.

Comentarii

  • Mulțumesc @Barmar, folosesc biblioteca ACE C++, speram să se ocupe de acest lucru…  > Por Avinash.
  • Cauzează o problemă? –  > Por Barmar.
  • M-am plâns că recv consumă mult procesor, așa că am căutat în direcția –  > Por Avinash.