1

I am trying to use boost file_lock to control two processes. I have process 1 obtaining a lock and then sleeping:

#include <boost/interprocess/sync/file_lock.hpp>
#include <fstream>
#include <chrono>
#include <thread>

int main()
{
    std::string lock_path = "lockfile";
    std::ofstream stream(lock_path, std::ios::app);
    boost::interprocess::file_lock lock(lock_path.c_str());
    if (lock.try_lock())
    {
        std::this_thread::sleep_for(std::chrono::seconds(30));
    }

    return 0;
}

while this process is sleeping, I will run a second process which tries to obtain the lock as well.

#include <boost/interprocess/sync/file_lock.hpp>
#include <iostream>

int main()
{
    boost::interprocess::file_lock lock("lockfile");
    if (lock.try_lock())
    {
        std::cout << "got here" << std::endl;
    }
    return 0;
}

I am expecting the cout statement on the second process not to print because the file is already locked by another process but it does print. What am I missing here? is file_lock not supposed to be used this way?

hbnoory
  • 37
  • 4

1 Answers1

1

The best explanation I can think of is when your processes accidentally refer to different files. This might occur when

  • the current working directories are not the same
  • the processes run in isolated environments altogether (e.g. dockerized)
  • the file has been deleted/recreated in the meantime (meaning the inode doesn't match, even though the filename does)

Here's a simplified program that can serve as both parties:

Live On Coliru

#include <fstream>
#include <iostream>
#include <thread>

#include <boost/static_assert.hpp>
#include <boost/interprocess/sync/file_lock.hpp>

namespace bip = boost::interprocess;
using namespace std::chrono_literals;
static inline auto constexpr lock_path = "lockfile";

int main() {
    bip::file_lock lock(lock_path);
    if (lock.try_lock()) {
        std::ofstream stream(lock_path, std::ios::app);
        std::cout << "got lock" << std::endl;
        std::this_thread::sleep_for(2s);
    }
    std::cout << "bye" << std::endl;
}

Local demo:

enter image description here

sehe
  • 374,641
  • 47
  • 450
  • 633