概要
C/C++で、タイムアウトが設定できないブロッキング処理に、タイムアウトを追加した。
背景と目的
C/C++のあるライブラリで、タイムアウトが設定できないブロッキング処理があり、処理をキャンセルできずに困ったので、後付けでタイムアウトを実装する方法を調べ、動作を確認する。
詳細
1.考え方
基本的には、スレッドによりブロッキング処理を行わせておいて、メインスレッドではタイムアウト期間が経過するまで待てばよいと考えた。
2.実装
C/C++には、pthreadというライブラリがあり、その中のpthread_timedjoin_np関数はタイムアウト付きのjoinである。なので、これを利用すればよい。
という感じで実装したのが以下。
#include <pthread.h> #include <time.h> #define TIMEOUT_LENGTH 5 // タイムアウト秒数[sec] // スレッドに渡す引数をまとめる構造体 struct tharg { // 必要なものを適宜 // : }; // スレッド void *thread_function(void *arg) { struct tharg * tharg = (struct tharg *) arg; // 引数受け取り // ブロッキング処理をここでおこなう // : } // タイムアウト処理 --------------------------------------- struct timespec ts; // タイムアウト時間 pthread_t th; // スレッド struct tharg_t *tharg = (struct tharg_t*) malloc(sizeof(struct tharg_t)); // スレッド引数 // タイムアウト長さ設定 if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { // エラー時 } ts.tv_sec += TIMEOUT_LENGTH; // スレッド開始 pthread_create(&th, NULL, thread_function, tharg ); if (pthread_timedjoin_np(th, NULL, &ts) != 0) { // タイムアウト時 pthread_cancel(th); // スレッドを強制的に止める pthread_join(th, NULL); } else { // 正常終了時 } free(tharg);
3. 動作確認
上記のような構成でプログラムを実装してみたところ、うまく動いた。なので、成功。