• ベストアンサー

プログラムの一時停止

OSはubuntu、言語はC++を用いております。 Ctl+Zは、メモリの中の実行ファイルのイメージを保存して一時停止しているのだと思いますが、 あんな感じで、再起動した後でも今まで動いていたプログラムを実行しつづけるというのは可能でしょうか? 理想を言えば、 「プログラム中に、データを書き込む(Ctl+Zに相当)ための命令があって、 定期的にその命令を実行し、 再起動後はその命令を最後に実行したところからもう一度実行する。」 ということです。

質問者が選んだベストアンサー

  • ベストアンサー
  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.6

再実行のために必要なデータが何か決まっていて、 再実行時に利用できるようにプログラムがそれらのデータを出力できるのなら何も難しくはないですものね。 再実行のための何かOSのサポートがないと、 たぶん、一般のプログラムでは困難でしょう。。。 === (signal() を使ってしまってますが(笑)) #include <iostream> #include <fstream> #include <csignal> #include <unistd.h> bool stop = false; unsigned int num_iter = 0; void handler(int sig) { using namespace std; signal(SIGUSR1, SIG_IGN); stop = true; } void do_work(unsigned int n) { std::cout << "hello, " << n << '\n'; sleep(3); } int main(int argc, char *argv[]) { using namespace std; if (argc > 1) { std::ifstream ifs(argv[1]); ifs >> num_iter; } std::cout << getpid() << '\n'; signal(SIGUSR1, &handler); while (true) { do_work(num_iter++); if (stop) { std::ofstream ofs("restart.txt"); ofs << num_iter << '\n'; break; } } } === % ./a.out 2680 hello, 0 hello, 1 hello, 2 hello, 3 % kill -USR1 2680 % ./a.out restart.txt 3432 hello, 4 hello, 5 ....

noname#108554
質問者

お礼

こちらの環境でコンパイルすると、最後の行のところで、 warning: no new line at end of file という警告がでるのですが、これはいいのでしょうか? 無視して実行すると、 PID hello, 0 hello, 1 hello, 2 hello, 3 ・・・ まではうまくいきます。そして、Ctrl+Zで止めて kill -USR1 PID とするわけですが、restart.txtというファイルは生成されません。

その他の回答 (8)

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.9

Ctrl-Z の発行するシグナル SIGTSTP はキャッチできる(SIGSTOP がキャッチ不可だったのかな。。。^^;)みたいですね。 なので、プログラムの SIGUSR1 のところを SIGTSTP に変えれば、 その端末で Ctrl-Z するだけでよくなります(kill -USR1 procid の代わりに)。 まぁ、stty かなにかで Ctrl-Z で SIGUSR1 が発行されるように変更しておけば見た目は同じですけどね^^ いずれにしてもシグナルは、きちんとしたプログラムでは 使わないほうがいいと思いますし、それでも使いたいというなら きちんと認識をしてからにするようにお勧めします。 システムコール呼び出し中にシグナルが発行された場合など システムコールが再実行されるのかされないのか、 シグナルの連射がきたときに大丈夫か、 シグナルが発行された回数きちんとキャッチできるのか、などなど。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.8

最終行に改行がないのは、コピペしたときに改行が入らなかっただけでは? あと、Ctrl-Z で発行されるシグナルはキャッチできないので、 Ctrl-Z で発行されるシグナルは処理できません。その時点でプログラムは停止しています。 なので、Ctrl-Z をしないで、別の端末などから、kill -USR1 procid のみしてみてくださいませ^^

noname#108554
質問者

お礼

>最終行に改行がないのは、コピペしたときに改行が入らなかっただけでは? そうみたいです。 他のプログラムは改行が入ろうと入るまいとちゃんと動くのですが・・・ それはともかく、動きました。ありがとうございます。 これが自分のプログラムでも使えるかどうか、検討してみます。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.7

こっちはもっと C 寄りで: 「再起動後に実行を再開する」の「再開する場所」が固定なら, 1.特定のタイミング (例: 定期的に) でデータを (特定のファイルに) ダンプする 2.再起動後に実行を再開するときには, 1 でダンプしたファイルの内容から「実行を再開するべき場所」などを見付ける という方針でできなくもないです. あんまりしたくないけど. そうじゃないと, ほとんど無理じゃないかなぁ. undump があれば別だけど....

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.5

スナップショット的な主記憶のコアイメージを保存して、 それを後に再開する機能が備わってるかどうかということなら、 プログラミング言語は関係なく、OSの機能の問題ですよね。 そのようなシステムコールがあるのかどうか、 「Linux系OS」のほうへ質問を投げてみれば?^^ わたしはまた、再開できるポイントをプログラム自身で決めていて、 そこにあわせてデータを吐けばいいようにと思っていて、 再開データ出力の指示のみ受け取る方法を回答すればいいのかと。。。思い違いしていたようですね。任意の時点なのですよね。。。

noname#108554
質問者

お礼

えーと、どちらでもいいです。 「Ctl+Zみたいな命令」で一時停止→再起動→プログラム再開 でもいいですし、 「プログラム中の再開できるポイント」で一時停止→再起動→プログラム再開 でもいいです。 あえていえば簡単なほう・・・ですかね。 Linux系OSでも質問してみますね。

回答No.4

ANo.1の人です。 そのプログラムがどんなプログラムか分かりませんから >実行の状態を自分で保存して、再開のときにそれを復元する必要がありますね。 と抽象的なことを書くしかないわけです。 処理に使っているすべての情報(変数の値など再開に必要なすべての情報)を自分で考えた形式でファイルに保存することになるでしょう。 > データを書き込む(Ctl+Zに相当)ための命令 を当該プロセスに送る必要があります。 関係のない他のプロセスに直接働きかける方法はシグナルしかないですから、 ・ANo.2さんの、当該プロセスがファイルの存在をときどきチェックする方法 ・当該プロセスがソケットを開いておいて、そこに接続があったら保存する方法 などの代わりの方法を考える必要があります。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.3

ほんとにシグナル処理をなされるのなら、 『詳解UNIXプログラミング』 W.リチャード・スティーヴンス著 大木 敦雄訳 税込価格 : \8,190 (本体 : \7,800) 出版 : ピアソン・エデュケーション ISBN : 4-89471-319-5 が、参考書としてお勧めです。ちと、高いですが^^;

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.2

Ctrl-Z はSIGTSTP でしたっけ?再開は SIGCONT だったでしょうか。。 これらのシグナルは、「無視」か「デフォルト動作」かしかできない(キャッチできない)規約になっていた気がします。 ご自分で SIGUSR1 などで、シグナルハンドラを登録すればできますよね。プログラムのプロセスにコマンドラインから kill コマンドかなにかで、キャッチすることにしたシグナルを送ればいいです。 シグナルをもし使うなら、<signal.h> の signal() とかではなく、 sigaction() のほうで取り扱ったほうがいいと思います。 しかし、シグナルは使わないに越したことはないので、 たとえば、起動時にでもフラグのための、ファイル名を指定しておいて、 プログラムで定期的にそのファイル名のファイルがあるかどうかチェックする。あればデータを書き込みフラグファイルを消し、なければデータを書かずに処理を続ける。。。みたいな仕組みにして、シグナルは 使わないようにするのがポータビリティがあると思いますし、 確実な動作が可能になると思います。

回答No.1

実行の状態を自分で保存して、再開のときにそれを復元する必要がありますね。 そして、シャットダウンを検知したら、上記の保存をおこなう必要があります。

noname#108554
質問者

お礼

ありがとうございます。 >実行の状態を自分で保存して、再開のときにそれを復元する必要がありますね。 ええ、そのとおりです。 >そして、シャットダウンを検知したら、上記の保存をおこなう必要があります。 まあ、そのとおりなんですが、そこまでは要求しません。 「データを書き込む(Ctl+Zに相当)ための命令」の次のところから 再開できれば十分です。 質問はその方法についてです。

関連するQ&A

専門家に質問してみよう