有没有办法在C++应用程序的多次执行中保存值?



例如,

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

这将在第一次打印第一次运行,并且程序在每次之后都运行。这可能吗?

编辑:文件不起作用,还有其他方法吗?

您需要将该计数器保存在应用程序之外的某个位置。变量存储在为进程保留的内存中。因此,当您的进程死亡时,内存中的值也会消失。

如果平面文件不起作用,其他选项可能是数据库,甚至是跟踪特定应用程序运行时的单独守护程序。但是,如果要在电源周期内保留计数器,则需要将该数据值保存在持久内存中的某个位置(例如硬盘驱动器)。

好的,所以这是它的要点:

如果您正在运行的内核不提供文件,则需要提供有关您正在使用的内核和/或设备的具体详细信息,以及是否需要在"重新启动"之间存储它们,因为无法将文件打包听起来非常具体。

如果您没有任何闪存/硬盘/SSD 或其他类型的"硬"来保存数据,则在执行之间保存值是不可能的,由于其动态性质,您无法将值保存在 RAM 中。

你可以做的是:

a) 编写你自己的原始 fs 管理工具,如果你的架构只运行你的应用程序,这应该很容易,因为你不需要做很多检查,但你需要有各种各样的静态内存来存储字节

b) 在执行结束时重新编译初始程序,并将要替换的值替换为当前程序中存在的值

c) 使用 a shell 将值保存在一些外部变量中:

#include <stdlib.h>
putenv("EXTERNAL_STATE=" + my_variable);

d) 将您希望通过网络保存的状态发送到具有文件系统的计算机,并从那里读取/写入它。

e) 有一个单独的应用程序,该应用程序在一段时间内运行并侦听来自控制台的输入。当它收到集合输入时,它以所述变量作为参数运行程序,当程序返回时,它会输出变量,"父"应用程序读取它并在内部设置它

我想到了使用boost库中的共享内存的想法。

这个概念是,程序第一次运行时,它会创建自己的另一个进程,只是使用特定参数调用(是的,它是一种分支,但通过这种方式,我们有一个可移植的解决方案)。并行进程只处理共享内存的初始化,并等待终止信号。

以下实现的主要缺点是,理论上,客户端(而不是管理器)的共享内存可以在服务器(处理共享内存)完成初始化之前打开。

哦,我只是以 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'; 
}
}

相关内容

  • 没有找到相关文章

最新更新