问题描述
我有一个情况,2个不同的进程(我的C + +,其他人在JAVA中做的)是一个作家和一些共享数据文件的读者。所以我试图通过编写类这样的类(编辑:这段代码是破碎,它只是一个例子)避免竞争条件
code> rmdir(),可以通过单一系统调用创建和删除原子。你不需要显式地测试锁的存在, em>取得锁定:
$ b sleep
unlock:
rmdir(lockfile)
我相信这甚至可以通过NFS(这通常吸引这种事情)。
但是,你可能还想看看正确的文件锁定,这是加载更好;我在Linux上使用(注意这些不同于群锁,尽管结构的名称)。这允许您正确地阻止,直到锁释放。如果应用程序死机,这些锁也会自动释放,这通常是一件好事。此外,这些将允许您直接锁定共享文件,而不必有一个单独的锁文件。这也在NFS上工作。
Windows具有非常类似的文件锁定功能,并且它还易于使用全局命名的信号量,这对于进程之间的同步非常方便。
I have a situation where 2 different processes(mine C++, other done by other people in JAVA) are a writer and a reader from some shared data file. So I was trying to avoid race condition by writing a class like this(EDIT:this code is broken, it was just an example)
class ReadStatus { bool canRead; public: ReadStatus() { if (filesystem::exists(noReadFileName)) { canRead = false; return; } ofstream noWriteFile; noWriteFile.open (noWriteFileName.c_str()); if ( ! noWriteFile.is_open()) { canRead = false; return; } boost::this_thread::sleep(boost::posix_time::seconds(1)); if (filesystem::exists(noReadFileName)) { filesystem::remove(noWriteFileName); canRead= false; return; } canRead= true; } ~ReadStatus() { if (filesystem::exists(noWriteFileName)) filesystem::remove(noWriteFileName); } inline bool OKToRead() { return canRead; } };
usage:
ReadStatus readStatus; //RAII FTW if ( ! readStatus.OKToRead()) return;
This is for one program ofc, other will have analogous class.Idea is:1. check if other program created his "I'm owner file", if it has break else go to 2.2. create my "I'm the owner" file, check again if other program created his own, if it has delete my file and break else go to 3.3. do my reading, then delete mine "I'm the owner file".
Please note that rare occurences when they both dont read or write are OK, but the problem is that I still see a small chance of race conditions because theoretically other program can check for the existence of my lock file, see that there isnt one, then I create mine, other program creates his own, but before FS creates his file I check again, and it isnt there, then disaster occurs. This is why I added the one sec delay, but as a CS nerd I find it unnerving to have code like that running.Ofc I don't expect anybody here to write me a solution, but I would be happy if someone does know a link to a reliable code that I can use.P.S. It has to be files, cuz I'm not writing entire project and that is how it is arranged to be done.
P.P.S.: access to data file isn't reader,writer,reader,writer.... it can be reader,reader,writer,writer,writer,reader,writer....
P.P.S: other process is not written in C++ :(, so boost is out of the question.
On Unices the traditional way of doing pure filesystem based locking is to use dedicated lockfiles with mkdir() and rmdir(), which can be created and removed atomically via single system calls. You avoid races by never explicitly testing for the existence of the lock --- instead you always try to take the lock. So:
lock: while mkdir(lockfile) fails sleep unlock: rmdir(lockfile)
I believe this even works over NFS (which usually sucks for this sort of thing).
However, you probably also want to look into proper file locking, which is loads better; I use F_SETLK/F_UNLCK fcntl locks for this on Linux (note that these are different from flock locks, despite the name of the structure). This allows you to properly block until the lock is released. These locks also get automatically released if the app dies, which is usually a good thing. Plus, these will let you lock your shared file directly without having to have a separate lockfile. This, too, work on NFS.
Windows has very similar file locking functions, and it also has easy to use global named semaphores that are very convenient for synchronisation between processes.
这篇关于正确的方式使用锁文件作为多个进程之间的锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!