gethostbyname timeout --- 轉(zhuǎn)
總結(jié): 下面第一種方法經(jīng)過測試是可行的,第二種方法(多線程中使用)不能夠用信號中斷。
so , 對信號的使用要非常小心。
gethostbyname 是阻塞的, 非線程安全的,所以最好使用getaddrinfo , 它是線程安全的。
要給gethostbyname 設(shè)置一個超時值, 用信號(alarm)實現(xiàn)是不行的(目前項目嵌入式平臺上面測試不行) 。
下面是網(wǎng)上摘錄的解決該問題的方法, 對怎么繞過其他系統(tǒng)函數(shù)(無論是線程安全還是非安全的)也有很好的借鑒意義
Hello,
I need to add timeout to gethostbyname function in my program. I
googled and searched archives, found some examples with alert(), but
can't make it work :/ I would be grateful of someone could tell me how
to do it.
You can't. Or rather, you shouldn't.
The trick with alarm(2) (not alert()), is to longjmp(3) from the signal
handler to a context created with setjmp(3) before calling gethostbyname(3).
This is, unfortunately, very common in Perl code (in Perl die() actually
uses longjmp() internally to a context set from an eval statement).
However, gethostbyname() keeps internal state, and afterward its unsafe
to call the function again. gethostbyname_r() might be relatively safer,
but you've probably also leaked a file descriptor and memory,
meaning you could only do it so many times from a single process before it
won't work anymore. (And from a strict C perspective, jumping from the
signal handler itself is questionable.)
You do have options.
1) Multiple processes. Use child processes and the
gethostbyname()+alarm() trick, and return the answer down a pipe to
the parent. The child will just kill itself if it timeouts (or
alternatively the parent will set the alarm and kill the child), since it
cannot reliably do it's job afterward.
2) Use threads in conjunction with gethostbyname_r(), or preferably
getaddrinfo(3). Still, you cannot interrupt these functions within the
thread, and so you have a few more decisions to make in terms of how you
handle timeouts.
3) Use a third-party asynchronous DNS library: ADNS, C-Ares and UDNS are
the first ones which comes to mind, the former two probably being the most
popular.