- PR -

コマンド終了待ち時のタイムアウト処理

投稿者投稿内容
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2006-10-03 15:36
引用:

finchさんの書き込み (2006-10-03 14:40) より:
なお、あしゅさんが「2006-10-02 18:38」に投稿された方法は、デッドロックになるのではないでしょうか?
(プロセス起動スレッドが「起動イベント」を確保している間に、タイムアウト監視スレッドからのnotifyを待つ。
タイムアウト監視スレッドは、notify発行の前に、「起動イベント」を確保できない。)



デッドロックにはなりませんよ。
起動スレッドをT1、監視スレッドをT2として、

(A) T1:起動イベントのモニターを獲得
(B) T1:監視スレッドをstart()

(C) T2:完了イベントのモニターを獲得
(D) T2:起動イベントのモニターを獲得 -> 不可(T1が獲得中)

(E) T1:起動イベントをwait() -> モニターを解放

(F) T2:起動イベントのモニターを獲得 -> 獲得可能
(G) T2:起動イベントをnotify()
(H) T2:起動イベントのモニターを解放

(I) T1:起動イベントのモニターを獲得
(J) T1:起動イベントのwait()から復帰
(K) T1:起動イベントのモニターを解放

という流れになります。

この時に、T2の開始(C,D)と(E)のwait()の実行順序は定まりませんが、
(C,D)は(E)の待機の復帰前には実行されることになるので問題ないです。

#実際にも(E)の待機中にT2が開始される可能性の方が高いと思います。
#実装依存(+プロセッサ数依存)ですが、T1は実行中であり、スレッドを
#起動したとしてもwait()で実行権を放棄するまでは奪われないでしょう。

言い換えると、(E)のwait()の復帰には(G)のnotify()が必要となり、
(E)のwait()から復帰させるタイミングはT2が握ることになるので、
その間に初期化処理を完了させる事が出来るわけです。
finch
常連さん
会議室デビュー日: 2006/09/29
投稿数: 26
投稿日時: 2006-10-03 19:03
引用:
(E) T1:起動イベントをwait() -> モニターを解放


waitでロックが解放されるのですね。
了解致しました。
参考にさせて頂きます。
finch
常連さん
会議室デビュー日: 2006/09/29
投稿数: 26
投稿日時: 2006-10-04 15:43
引用:
あしゅさんの書き込み (2006-10-02 18:38) より:
java.util.concurrent.ExecutorServiceにプロセス起動をsubmit()して、
Futureをタイムアウト付きで待機する方法がスマートかもしれません。


下記のようなコードで、割合シンプルに実装できそうです。

コード:
/*メイン*/
import java.util.concurrent.*;
class Main {
	public static void main( String argv[] )  {
		ExecutorService ex = Executors.newCachedThreadPool();
		String cmd[] = {"xxx", "yyyy"};
		Future<Integer> f = ex.submit(new ProcessThread(cmd));
		try {
			Integer intV = f.get(タイムアウト値, TimeUnit.SECONDS);
		}
		catch(TimeoutException e) {
			f.cancel(true);
		}
		catch(InterruptedException e) {
		}
		catch(CancellationException e) {
		}
		catch(ExecutionException e) {
		}
		ex.shutdown();
	}
}

/*コマンド発行スレッド*/
import java.util.concurrent.*;
import java.io.*;
class ProcessThread implements Callable<Integer> {
	String[] cmd;
	ProcessThread(String[] cmd){
		this.cmd=cmd;
	}
	public Integer call(){
		Process process=null;
		try { 
			process=Runtime.getRuntime().exec(cmd);
		}catch(IOException e){
		}
		try { 
			process.waitFor(); 
		}catch(InterruptedException e){
 			process.destroy();
		}
		return 0;
	}
}



スキルアップ/キャリアアップ(JOB@IT)