どうも、setjmp / longjmp と alarm がすこぶる相性が悪いみたいなので、alarm だけ使ってできないか考えてみた。
static struct hostent *lpHostEnt = NULL; typedef struct hostMode{ char* host; //ターゲット引数 int timeout; // 函数のタイムアウト struct hostent *flag; // ループ用のフラグ }_hostMode;
static void alarm_func(int erno) { lpHostEnt = NULL; printf("gethostbyname: timeout\n"); }
static void* thread(void *arg) { struct hostMode *hm = (struct hostMode*)arg; if (lpHostEnt == hm->flag){ printf("gethostbyname: 警告:まだ前の処理が終わっていません\n"); } else { lpHostEnt = hm->flag; } pthread_detach(pthread_self()); // スレッドを分離 signal(SIGALRM, alarm_func); alarm(hm->timeout); // タイムアウトの設定 lpHostEnt = gethostbyname(hm->host); signal(SIGALRM, SIG_IGN); printf("gethostbyname: function end\n");}
static struct hostent *timeGethostbyname(const char *domain, int timeout) { //threadDomain = (char*)domain; pthread_t thread_id; struct hostMode hm; struct hostent dummyHost; hm.timeout = timeout; hm.host = (char*)domain; hm.flag = &dummyHost; int rc = pthread_create(&thread_id, NULL , thread, (void*)&hm); if(rc == 0){ pthread_join(thread_id, NULL); while(lpHostEnt == &dummyHost); } return lpHostEnt; } |
原理としては、スレッドを起動して、gethostbyname をalarm 付で 実行
ただし、join したあとスレッドを切り離すので、スレッドはバックグラウンドで動く
タイムアウトで、返り値だけが、変化する仕組みにして、pthread_join の代わりに while で待つ仕様に変更。
注意点としては、マルチスレッドセーフではないので、タイムアウト時間内に関数をもう一度呼ぶとだめってことくらい (((・ω・)))
これでいちおう動いた。
サイトのタイムスタンプ狂ってませんか?
この記事7月6日の記事ですけど
日付が6月22日になってますよ
この記事に限らず3つ前ぐらいから
日付が6月21日で止まってますし