I am trying to use file_lock for restricting multiple instances of the same program running at the same time (Implementing something mentioned in this answer). I am using 1.66
version of boost on Linux
.
Before locking the file, I make sure that file exists (by opening it using std::ofstream
with std::ios::app
). I noticed one thing, if we close the stream, then file_lock
is automatically unlocked and hence, allowing multiple instance of the same program to run at the same time.
The program below doesn't work as file_lock is automatically released.
int main(int argc, char *argv[])
{
namespace bipc = boost::interprocess;
if (argc < 2)
return 0;
std::string path = argv[1];
std::string lock_path = "/var/lock/" + path + ".lock";
std::ofstream stream(lock_path, std::ios::app);
bipc::file_lock lock(lock_path.c_str());
if (!lock.try_lock())
throw std::runtime_error("Multiple instance");
std::cout << "Running" << std::endl;
stream.close();
while (true)
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0;
}
However, the two programs below works.
Looks like if we have opened a file while trying to acquire the file_lock, then we need to keep that file opened till we want to hold the lock. If we close the file, then lock is automatically released. I am not sure if this is a bug. Can someone help me with the reason of such behavior?
int main(int argc, char *argv[])
{
namespace bipc = boost::interprocess;
if (argc < 2)
return 0;
std::string path = argv[1];
std::string lock_path = "/var/lock/" + path + ".lock";
std::ofstream stream(lock_path, std::ios::app);
bipc::file_lock lock(lock_path.c_str());
if (!lock.try_lock())
throw std::runtime_error("Multiple instance");
std::cout << "Running" << std::endl;
while (true)
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0;
}
And
int main(int argc, char *argv[])
{
namespace bipc = boost::interprocess;
if (argc < 2)
return 0;
std::string path = argv[1];
std::string lock_path = "/var/lock/" + path + ".lock";
{
std::ofstream stream(lock_path, std::ios::app);
}
bipc::file_lock lock(lock_path.c_str());
if (!lock.try_lock())
throw std::runtime_error("Multiple instance");
std::cout << "Running" << std::endl;
while (true)
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0;
}