开发者

Atomically locking multiple files

What is the best way to atomically lock multiple files? One possibility I've thought of is a simple .lock file in the directory (I'm only protected from other instances of my program; I'm not necessarily trying to thwart other programs from disrespecting the lock.) However, everything I've learned about thread-safety screams "bad idea!" Would this be a safe way to go? Is trying to create a file atomic, so if I succeed in creating it, I know I have the lock? How should I go about this?

I'm writing my own bug tracker (mostly as an exercise, I know I could find good solutions out there,) which stores bugs in files on the network. I envision it kind of like SVN - a single directory gets taken over by the program, and used to hold bugs, revis开发者_运维问答ions, screenshots, etc, all managed by the tracker. I'm assuming SVN has a way to ensure multiple clients don't make commits at the exact same time, etc.


Open each file exclusively, if you find one that can't be opened, then unlock the ones you've already locked. Always lock in alphabetical order to avoid deadlocks.

    private List<FileStream> OpenExclusive(List<string> filenames)
    {
        var streams = new List<FileStream>(filenames.Count);

        try
        {
            filenames.Sort();
            foreach (var name in filenames)
            {
                streams.Add(File.Open(name, 
                  FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None));
            }
            return streams;
        }
        catch (Exception)
        {
            CloseAll(streams);
            return null;
        }
    }

    private void CloseAll(List<FileStream> streams)
    {
        if (streams == null) return;
        foreach (var stream in streams)
        {
            stream.Close();
        }
    }


i recommend Mutex, named mutex is operation system wide.


If you open a file for exclusive access, it will remain locked in that anyone else attempting to open it will fail.


One simple and reliable option is to have your application rename the directory containing those files before it starts using them. It can rename the directory to a random name before it starts and rename it back when it finishes. If the rename is successful, there's no possibility of a conflict.

One disadvantage is that if an application instance fails to rename the directory back, others will be locked out forever. You might be able to come up with some scheme in which the renamed directory name encodes the time it was renamed. If other instances see that a timeout period has passed, they can take control of it.

Have you looked into existing libraries so that you won't have to come up with your own solution and deal with all the edge cases? I unfortunately don't know of any off the top of my head.


I want multiple users submitting bugs from various places on the network.

Use a database engine.

Perhaps you're right, but then I'm curious how SVN works. It appears to me that there are no servers, all the clients simply access a standard structure of files in your SVN directory.

http://www.pushok.com/soft_svn_vscvs.php says that SVN is based on a BerkleyDB.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜