17

幅広い質問があります:

私がC++プログラムを持っていて、内部で設定できるいくつかの構成を使用して、バックグラウンドでファイルに対して実行を開始したとします。実行中に、これらの内部構成を変更し、コンパイルして、別のファイルで実行を開始しました。

これは、すでにバックグラウンドで実行されていた前のインスタンスに影響しますか?またはそれはすでに稼働していたので、そうではありませんか?これに関するアイデアは大歓迎です。

4

3 に答える 3

20

実行中の実行可能ファイルを変更することは安全ではありません。メモリマップされた実行可能ファイルを上書きするとどうなりますか

Linuxでは、実行中に実行可能ファイルを置き換えると、結果が予測できず、クラッシュする可能性があります。

ファイルを削除して新しいバージョンのプログラムをコンパイルすると、何が起こるかは非常に明確に定義されています。すでに実行されているインスタンスは前のコードを使用し、プログラムが終了するまでオペレーティングシステムによってメモリに保持されます。新しいインスタンスはすべて新しいコードを使用します。

要約:ビルドシステムが再コンパイルする前に古い実行可能ファイルを削除することを確認する必要があります。それがtrueである限り、プログラムを再実行するまで再コンパイルは有効になりません。そうでない場合、動作は未定義です(SIGSEGVを参照)。

ある種の付録:

JamesKanzeは、リンカ自体が出力を書き込む前にファイルを削除する可能性があることを正しく指摘しました。この場合、再コンパイルする前にファイルを自分で削除したかのように常に動作します(正常なシナリオ)。binutilscvsヘッドからbfd/cache.cを見る:

/* Create the file.

   Some operating systems won't let us overwrite a running
   binary.  For them, we want to unlink the file first.

   However, gcc 2.95 will create temporary files using
   O_EXCL and tight permissions to prevent other users from
   substituting other .o files during the compilation.  gcc
   will then tell the assembler to use the newly created
   file as an output file.  If we unlink the file here, we
   open a brief window when another user could still
   substitute a file.

   So we unlink the output file if and only if it has
   non-zero size.  */

したがって、少なくともGNU LDでは、これで問題がないことが保証されています。ただし、これは必ずしも他のリンカーに拡張されるわけではありません。

于 2012-08-20T16:03:16.243 に答える
6

何が起こるか/起こるかはOSによって異なりますが、一般に、古いプログラムが新しいコードで実行を開始することはありません。Windowsではファイルがロックされて上書きできないと思うのでOSに依存していると言いますが、Linuxでは古いファイルのリンクを解除する必要がありますが、プログラムは引き続きその古いバージョンを使用します。新しいバージョンは技術的には別のファイルになります。

ここに注意点があります。ダイナミックライブラリまたはその他のダイナミックコードリソースがある場合は、新しいバージョンを入手できる可能性があります。いずれの場合も、オンデマンドでライブラリをロードすると、ロードするバージョンがロード時に存在するバージョンになります。ほとんどの場合、すべてのライブラリはプログラムの開始時に直接ロードされます。ただし、そうでない一般的なケースの1つは、必要に応じてロードされるプラグインアーキテクチャです。

于 2012-08-20T15:58:11.377 に答える
4

いいえ、元の実行中のインスタンスには影響しません。これはすでにメモリにロードされており、変更されません。

于 2012-08-20T15:55:25.953 に答える