gpt4 book ai didi

C++ Ubuntu在终止时不释放对锁定文件的锁定

转载 作者:行者123 更新时间:2023-11-28 01:41:10 25 4
gpt4 key购买 nike

我有一个 C++ 脚本,它检查是否需要执行任何操作,如果需要,它会启动正确的处理器 C++ 脚本。但是,由于它每 x 分钟运行一次,它还会使用锁定文件检查处理器是否仍在运行。

我使用以下函数获取锁:

int LockFile(string FileNameToLock) {
FileNameToLock += ".lock";
int fd = open(FileNameToLock.c_str(), O_RDWR | O_CREAT, 0666);
int rc = flock(fd, LOCK_EX | LOCK_NB);
if (rc || rc == -1) {
cout << errno << endl;
cout << strerror(errno) << endl;
return -1;
}
return fd;
}

正在执行的代码:

[...]
if (LockFile(ExecuteFileName, Extra) == -1) {
cout << "Already running!" << endl; //MAIN IS ALREADY RUNNING
//RETURNS ME Resource temporarily unavailable when processor is running from an earlier run
exit(EXIT_SUCCESS);
}
if (StartProcessor) { //PSEUDO
int LockFileProcessor = LockFile("Processor");
if (LockFileProcessor != -1) {
string Command = "nohup setsid ./Processor"; //NOHUP CREATES ZOMBIE?
Command += IntToString(result->getInt("Klantnummer"));
Command += " > /dev/null 2>&1 &"; //DISCARD OUTPUT
system(Command.c_str());
//STARTS PROCESSOR (AS ZOMBIE?)
}
}

第一次运行效果很好,但是当主脚本再次运行时,锁定文件返回 - 1,表示发生错误(仅当处理器仍在运行时)。 errno 为 11,这会导致错误消息:Resource temporary unavailable请注意,这只会在(僵尸)处理器仍在运行时发生。 (但是,主脚本已经终止,应该关闭文件句柄?)

出于某种原因,僵尸将主脚本的锁定文件的文件句柄保持打开状态???

我不知道去哪里寻找这个问题。

已解决:看我的回答

最佳答案

不,11 是 EAGAIN/EWOULDBLOCK 这仅仅意味着您无法获取锁,因为资源已经被锁定(参见 the documentation )。由于 LOCK_NB 标志,您收到了该错误(而不是阻止行为)。

编辑: 经过一些讨论,问题似乎是由于子处理时保留了 flock() 锁。为避免此问题,我建议在整个生命周期内不要使用 flock(),而是使用 touch-and-delete-at-exit 策略:

  1. 如果file.lock存在则退出
  2. 否则创建file.lock并开始处理
  3. 在退出时删除 file.lock

当然这里有竞争条件。为了确保安全,您需要另一个包含 flock 的文件:

  1. 群(common.flock)
  2. 如果file.lock存在则退出
  3. 否则创建file.lock
  4. 解锁flock(common.flock)
  5. 开始处理
  6. 在退出时删除file.lock

但这仅在您希望同时调用 main 时才有意义。如果你不这样做(你说 cron 每 10 分钟启动一次进程,这里没有竞争)然后坚持第一个版本。

旁注:这是此类(非同步)文件锁的简单实现:

#include <string>
#include <fstream>
#include <stdexcept>
#include <cstdio>

// for sleep only
#include <chrono>
#include <thread>

class FileLock {
public:
FileLock(const std::string& path) : path { path } {
if (std::ifstream{ path }) {
// You may want to use a custom exception here
throw std::runtime_error("Already locked.");
}
std::ofstream file{ path };
};

~FileLock() {
std::remove(path.c_str());
};

private:
std::string path;
};

int main() {
// This will throw std::runtime_error if test.xxx exists
FileLock fl { "./test.xxx" };
std::this_thread::sleep_for(std::chrono::seconds { 5 });
// RAII: no need to delete anything here
return 0;
};

需要 C++11。请注意,此实现不是竞争条件安全的,即您通常需要 flock() 构造函数,但在这种情况下它可能没问题(即当您不并行启动 main 时)。

关于C++ Ubuntu在终止时不释放对锁定文件的锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47091263/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com