Is there a way to preserve value for multiple executions of a C ++ application?

For instance,

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

This will print the first run for the first time, and the program starts every time after that. Is this even possible?

EDIT: the file will not work, is there any other way?

+4
source share
3 answers

You need to save this counter somewhere outside the application. Variables are stored in memory reserved for the process. Therefore, when your process dies, the values ​​in memory also disappear.

, , , , . , - (, ).

+7

, :

, , , , ​​/ , "", .

/hdd/ssd "" , , - .

:

a) , - , , ,

b) , , ,

c) :

   #include <stdlib.h>

   putenv("EXTERNAL_STATE=" + my_variable);

d) , , , , / .

e) , . , , , , ""

+1

boost.

, , (, , ). .

The main disadvantage of the following implementation is that theoretically the total memory of the client (and not the manager) can be opened before the server (which processes the shared memory) completes the initialization.

Oh, I just print the run index in base 0, just for demonstration. Here is the code.

#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'; 
    }
}
+1
source

Source: https://habr.com/ru/post/1679733/


All Articles