2010-08-06 2 views
1

여러 파일을 원자 적으로 잠그는 가장 좋은 방법은 무엇입니까? 내가 생각한 한 가지 가능성은 디렉토리에있는 .lock 파일입니다 (나는 다른 프로그램의 다른 인스턴스 인 프로그램에 대해서만 보호하고 있으며, 잠금을 무시한 다른 프로그램을 방해하지는 않습니다.) 그러나 모든 것 스레드 안전성에 대해 배웠던 "나쁜 생각!" 이것이 안전한 방법일까요? 원 자성 파일을 만들려고합니다. 따라서 파일을 만드는 데 성공하면 자물쇠가있는 것입니다. 이 문제를 어떻게 해결해야합니까?여러 파일을 원자 적으로 잠그는 것

필자는 자신의 버그 추적기 (주로 운동으로, 나는 거기서 좋은 해결책을 찾을 수 있음을 알고있다)를 작성하여 네트워크상의 파일에 버그를 저장한다. 나는 SVN과 같은 것을 상상한다. 하나의 디렉토리가 프로그램에 의해 인수되고, 추적자에 의해 관리되는 버그, 개정판, 스크린 샷 등을 잡는 데 사용된다. 나는 SVN이 여러 클라이언트가 정확히 같은 시간에 커밋을하지 못하도록하는 방법이 있다고 가정하고있다.

+1

더 나은 대답은 클라이언트/서버 아키텍처로 이동하여 서버 만 파일에 액세스 할 수 있도록하는 것입니다. –

+0

클라이언트/서버 아키텍처가이 응용 프로그램에 너무 복잡합니다. 대부분 저장소를 찾고 있습니다. – dlras2

+0

어떤면에서는 더 복잡하고 다른면에서는 더 간단합니다. –

답변

1

열 수없는 파일을 찾은 경우 각 파일을 단독으로 열고 잠근 파일을 잠금 해제하십시오. 교착 상태를 피하려면 항상 알파벳 순서로 잠급니다.

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(); 
     } 
    } 
0

나는 뮤텍스가 운영 체제 와이드라는 이름을 추천한다.

+0

하지만 네트워크를 통해 작동합니까? – dlras2

+0

@Daniel Rasmussen 아니요 – Andrey

+0

* @ Andrey * 그런 종류의 문제는 다음 단계입니다. 여러 사용자가 네트워크의 여러 위치에서 버그를 제출하고 싶습니다. – dlras2

0

독점 액세스를 위해 파일을 열면 해당 파일을 열려고 시도하는 다른 누군가가 실패하게됩니다.

+0

그래서 ".lock"파일의 존재 *가 아니지만 누가 그 파일에 대한 액세스 권한을 보유하고 있는지 제안하고 있습니까? – dlras2

+0

저는 잠금 파일이 유닉스라고 말하고 있습니다. Windows에서는 컨벤션이 아닌 OS를 사용합니다. –

+0

하지만 동시에 여러 파일에 단독으로 액세스해야하는 경우 어떻게해야합니까? 하나를 잠글 수 없으면 교착 상태가 될 수 있으므로 다른 하나를 잠글 수 있다고 가정합니다. – dlras2

0

하나의 간단하고 신뢰할 수있는 옵션은 응용 프로그램에서 파일을 사용하기 전에 해당 파일이 포함 된 디렉토리의 이름을 바꾸도록하는 것입니다. 디렉토리를 시작하기 전에 임의의 이름으로 바꿀 수 있으며 디렉토리가 끝나면 이름을 바꿀 수 있습니다. 이름 바꾸기가 성공적이면 충돌 할 가능성이 없습니다.

한 가지 단점은 응용 프로그램 인스턴스가 디렉터리의 이름을 바꿀 수없는 경우 다른 사람이 영원히 잠길 수 있다는 것입니다. 이름이 바뀐 디렉토리 이름이 이름이 바뀐 시간을 인코딩하는 체계를 생각해 낼 수 있습니다. 다른 인스턴스에서 시간 초과 기간이 지나면 해당 시간을 제어 할 수 있습니다.

기존 라이브러리를 조사해 보았습니다. 자신의 솔루션을 생각해 내고 모든 엣지 케이스를 처리 할 필요가 없습니까? 나는 불행히도 내 머리 꼭대기에서 어떤 것이 있는지 모른다.

+0

이것은 바퀴를 재발 명하고 있습니다. 이미 파일을 잠그는 내장 된 방법이 있습니다. –

+0

@Steven - 여러 파일을 원자 적으로 잠글 수있는 기본 제공 방법이 없습니다. – jthg

+0

사실, 실제로 있습니다. 일반적으로 사용되지는 않지만 I/O를 파일 처리 할 수있는 트랜잭션 모드가 있습니다. 그렇다고 여기에서 사용할 필요는 없습니다. 최악의 경우, 전체 디렉토리를 파일로 가득 채우려면 파일을 사용하기 전에 디렉토리를 단독으로 잠글 수 있습니다. –

0

내가 네트워크의 다양한 장소에서 버그를 제출하는 여러 사용자를 원한다.

데이터베이스 엔진을 사용하십시오.

아마도 당신 말이 맞겠지 만, 그렇다면 SVN의 작동 방식이 궁금합니다. 저에게는 모든 서버가 존재하지 않는 것처럼 보입니다. 모든 클라이언트는 SVN 디렉토리에있는 표준 구조의 파일에 간단히 액세스합니다.

http://www.pushok.com/soft_svn_vscvs.php은 SVN이 BerkleyDB을 기반으로한다고 말합니다.

관련 문제