2017-06-20 8 views
4

C++アプリケーションの複数回の実行で値を保存する方法はありますか?例えば

int var; 
int main() { 
    if(var==5) { 
     cout<<"Program has been run before"<<endl; 
    } 
    else { 
     var = 5; 
     cout<<"First run"<<endl; 
    } 
} 

これは、まず、印刷、初めてを実行し、プログラムが後の各時間前に実行されています。これはまったく可能ですか?

EDIT:ファイルは機能しませんが、他の方法はありますか?

+2

唯一の標準的なメカニズムは、ファイルを使用することです。他のソリューションはプラットフォームに依存します。 –

+0

@FrançoisAndrieuxプラットフォームに依存するソリューションを知っていますか? –

+0

プレーン・ファイルのみが動作しません(データベースは機能しますか?)あなたのターゲットプラットフォームは何ですか? Linux? Windows? – nefas

答えて

7

アプリケーションの外側のどこかにそのカウンタを保存する必要があります。変数は、プロセス用に予約されているメモリに格納されます。したがって、プロセスが終了すると、メモリ内の値も消えてしまいます。

フラットファイルが機能しない場合、他のオプションはデータベースでも、特定のアプリケーションの実行時間を追跡する別のデーモンでもかまいません。しかし、あなたはパワーサイクルにわたってカウンタを保持したい場合は、あなたが永続的なメモリのどこかにそのデータ値を保存する必要があります(例えば、ハードドライブ)

+1

なぜ人々はこれをdownvotingしているかわからない... – quinz

+0

私は以前、この答えはそれがまだ1または2文だったとき、それは非常に早いdownvotesを持っていることに気づいた。人々は恐らく元の不完全な答えを下落させ、決して戻ってチェックしなかった。当初、あなたの答えは「あなたはアプリケーションのどこかにそのカウンタを保存する必要があります」と言っただけです。 –

+0

ああ、彼らは本当に速く描いています。それは数秒の問題でした。しかし、感謝、私はdownvotesがレブ1のためだと思った。 – quinz

1

オクラホマので、ここでの要点だ:

カーネルあなたの場合実行しているファイルには、使用しているカーネルやデバイスの詳細や、再起動の間にそれらを保存する必要がある場合には、ファイルを提供できません。

フラッシュ/ hdd/ssdなどのデータを保存するための他のタイプの「ハード」がない場合、実行間の値を保存することは不可能です。その動的な性質のためにRAMに値を保存することはできません。

何を行う可能性がある:

a)は、お使いのアーキテクチャが唯一のこれまでのアプリを実行している場合は、チェックの多くを行う必要はありませんので、ご自身のプリミティブFS管理ツールは、これは簡単なはず書くが、あなたは、最初のプログラムを再コンパイル実行の終わりに

B)にバイトを保存し、あなたが

あなたの現在のプログラムに存在するものと交換したい値を置き換えるために種類の静的なメモリを持っている必要があります

c)シェルを使用して、いくつかの外部変数に値を保存します。

d)ネットワーク経由で保存したい状態を、ファイルシステムを持つマシンに送信し、そこから読み書きします。

e)しばらくのうちに実行され、コンソールからの入力を待ち受ける別のアプリケーションを用意してください。入力を受け取ると、その変数をパラメータとしてプログラムを実行し、プログラムが戻り値を出力し、 "親"アプリケーションがそれを読み取って内部的に設定すると、

+1

エクスポートソリューションでは、変数をプログラムの外にエクスポートしてプログラムからのみ変更するほうがよいでしょうか?私が覚えていることから、 '' export''は変数を子にエクスポートします。変数が、プログラム親によってエクスポートされない場合、プログラムが停止すると削除されます。 (私が間違っていると申し訳ありません) – nefas

+0

おそらくもっと明示的な方法を追加しましたが、env変数と扱う方法はシステム固有のものです。私もposixのその部分を確認していない – George

1

を共有するというアイデアが出ましたブーストライブラリのメモリ

概念は、プログラムが初めて実行されるときに、特定のパラメータで呼び出された別のプロセスを作成することです(はい、これは一種のフォークですが、この方法ではポータブルソリューションがあります)。並列処理は共有メモリの初期化を処理し、終了信号を待つだけです。

次の実装の主な欠点は、(共有メモリを扱う)サーバーの初期化が完了する前に、理論的には、クライアント(ない管理者)の共有メモリを開くことができ、ということです。

ああ、デモンストレーションのためだけに、ベース0の実行インデックスを印刷しています。ここにコード。

#include <cstring> 
#include <iostream> 
#include <thread> 
#include <chrono> 
#include <mutex> 
#include <condition_variable> 
#include <csignal> 

#include <boost/process.hpp> 
#include <boost/interprocess/shared_memory_object.hpp> 
#include <boost/interprocess/mapped_region.hpp> 

static constexpr const char* daemonizer_string = "--daemon"; 
static constexpr const char* shared_memory_name = "shared_memory"; 

static std::mutex waiter_mutex; 
static std::condition_variable waiter_cv; 

struct shared_data_type 
{ 
    std::size_t count = 0; 
}; 

extern "C" 
void signal_handler(int) 
{ 
    waiter_cv.notify_one(); 
} 

int main(int argc, const char* argv[]) 
{ 
    namespace bp = boost::process; 
    namespace bi = boost::interprocess; 

    if(argc == 2 and std::strcmp(argv[1], daemonizer_string) == 0) 
    { 
     struct shm_remove 
     { 
      shm_remove() { bi::shared_memory_object::remove("shared_memory"); } 
      ~shm_remove() { bi::shared_memory_object::remove("shared_memory"); } 
     } shm_remover; 

     bi::shared_memory_object shm(bi::create_only, shared_memory_name, bi::read_write); 

     shm.truncate(sizeof(shared_data_type)); 
     bi::mapped_region region(shm, bi::read_write); 
     void* region_address = region.get_address(); 
     shared_data_type* shared_data = new (region_address) shared_data_type; 

     std::signal(SIGTERM, signal_handler); 

     { 
      std::unique_lock<std::mutex> lock(waiter_mutex); 
      waiter_cv.wait(lock); 
     } 

     shared_data->~shared_data_type(); 
    } 
    else 
    { 
     bi::shared_memory_object shm; 
     try 
     { 
      shm = bi::shared_memory_object(bi::open_only, shared_memory_name, bi::read_write); 
     } 
     catch(std::exception&) 
     { 
      using namespace std::literals::chrono_literals; 
      bp::spawn(argv[0], daemonizer_string); 
      std::this_thread::sleep_for(100ms); 
      shm = bi::shared_memory_object(bi::open_only, shared_memory_name, bi::read_write); 
     } 

     bi::mapped_region region(shm, bi::read_write); 
     shared_data_type& shared_data = *static_cast<shared_data_type*>(region.get_address()); 
     std::cout << shared_data.count++ << '\n'; 
    } 
} 
関連する問題