问题
我的 C++ 应用程序作为 systemd 服务运行。我需要使用环境变量对其进行配置,并且能够在运行时重新加载变量的值,而无需重新启动应用程序。
我创建了一个.conf文件并使用环境其中的指令,我在更改中的值后执行 daemon-reload.conf文件。但该服务没有注意到这种变化。
我知道关于systemctl 重新加载命令,但我不知道要设置什么执行重载指示。
C++应用程序代码
#include <unistd.h>
#include <fstream>
using namespace std;
int main(int argc, char** argv)
{
while (true)
{
char * cp = getenv("BAR");
string s = "";
if (cp)
s = (string) cp;
fstream fs;
fs.open("/tmp/foo", ios_base::app);
fs << s << endl;
fs.close();
sleep(1);
}
return 0;
}
服务说明
路径:/etc/systemd/system/foo.service
[Unit]
Description=Testing configuration reloading
[Service]
ExecStart=/home/user/foo_application
Type=simple
[Install]
WantedBy=default.target
服务配置文件
路径:/etc/systemd/system/foo.service.d/foo.conf
[Service]
Environment="BAR=2"
我之前的(重新)搜索
https://serverfault.com/a/590732/379539
https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html
https://www.freedesktop.org/software/systemd/man/systemctl.html
答案1
创建进程时,环境被复制到进程的地址空间中。环境的改变只会影响新启动的进程,你不能从外部改变正在运行的程序的环境。
您将需要某种进程间通信(IPC)机制来实现您想要实现的目标,或者只是将新值写入文件并让程序轮询文件的内容。
答案2
除非您愿意重新启动正在考虑的服务(即终止正在运行的进程并启动新的进程),否则这是行不通的。环境变量是进程的单独属性,它们从父进程继承启动(即当父进程fork
s 时)。无法更改正在运行的进程的环境变量(不考虑像通过直接操作进程内存这样的黑客行为/proc/pid/mem
)。因此,即使通过唤醒进程SIGUSR1
并让它重新读取其配置(正如许多服务和守护进程的实现那样)也无济于事 - 该进程将找到与以前完全相同的环境变量。
对于您要求的行为,我建议您考虑从文件中获取配置参数。