1. 多線程中,一個線程阻塞在recv,另一個線程向它發信號試圖喚醒阻塞線程失敗,
仍然阻塞在recv調用。
解決方法:a.給socket設置recv超時選項: setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
tv所代表的時間不能為0,也不能太長。
tv時間最長能有多長取決於系統實現,我在Fedora18 64bitPC上測試時可以設置1個月,但是在LFS x86 32bits上測試失敗。當LFS系統設置短時間如10分鐘的超時值時信號是可以喚醒recv的,但未嘗試測出邊界值。
b. 使用sigaction,sa_flag不能設為SA_RESTART。ex:
static Sigfunc* _signal(int signum, Sigfunc* func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
#if 0
if (signum != SIGALRM)
act.sa_flags |= SA_RESTART;//SA_NODEFER;
#endif
if (sigaction(signum, &act, &oact) < 0)
return (SIG_ERR);
return oact.sa_handler;
}