2016-09-20 8 views
0

원칙적으로 내가 원하는 것은 매우 간단하다.폴링없이 리눅스 동기화

두 개의 실행 파일 ./read./write은 각각 리소스 (파일이라고 가정)에서 읽고 씁니다. flock(2)을 사용하면 임의의 시간에 ./read./write의 임의 호출 사이의 경쟁 조건을 쉽게 방지 할 수 있습니다.

요구 사항은 ./read의 각 호출이 이전 호출에서 자원의 스냅 샷을 포함, 현재 자원이 스냅 샷과 일치하는 경우 ./write의 호출이 자원을 변경 할 때까지, ./read이 (수면) 기다려야한다는 것입니다. 내가 수집 무엇부터

는 각 프로그램의 프로그램 흐름은해야 뭔가 같은 :

//read.c 
obtain mutex0 
    read resource 
    is resource same as our snapshot? 
    release mutex0 [1] 
    sleep until ./write says to wake up [2] 
    obtain mutex0 
    read resource 
    do something with resource 
release mutex0 

//write.c 
obtain mutex0 
    change resource in some way 
    tell any sleeping ./read's to wake up 
release mutex0 

이 방법의 가장 큰 문제는 [1][2]를 표시된 선 사이의 명백한 지연이 있다는 것입니다. 이것은 ./read[1]에서 mutex0을 해제 할 수 있습니다 ./write의 전체 호출을 완료 할 수 있으며, 다음 [2] 실행하는,하지만 ./write 이미 전에 자고 ./read들 일어나려고하기 때문에 무한정 멈출 것을 의미합니다.

전체 분리 된 전체 서버 프로세스를 사용하는 것 외에 원하는 작업을 수행하는 쉬운 방법이 있습니까? 또한, 그 호기심에 나는 CGI에서 응용 프로그램을 위해 이것을하고 싶습니다.

+1

뮤텍스 대신 세마포어를 사용할 수 있습니다. – Riley

+0

프로세스 간 통신을 원한다고 생각됩니다. 난 당신의 임시 계획보다는 리눅스의 명명 된 파이프 또는 [ZeroMQ] (http://czmq.zeromq.org/)를 읽는 것이 좋습니다. – orlp

+0

귀하의 의견 중 어느 쪽도 제가 지적한 경쟁 조건을 언급하지 않았습니다. 세마포어에 대해 알고 있습니다. IPC에 대해 알고 있습니다. –

답변

1

아니요, 프로그램 흐름이 잘못되었습니다. 하나 이상의 읽기가 진행되는 동안 쓰기를 방지하기위한 일종의 잠금 메커니즘과 쓰기가 완료 될 때마다 독자에게 알리는 일종의 웨이크 업 메커니즘이 필요합니다.

작가 (들)에 대한 귀하의 프로그램 흐름이 괜찮 :

# Initial read of file contents 
    Obtain lock 
     Read file 
    Release lock 

    # Whenever wishes to modify file: 
    Obtain lock 
     Modify file 
     Signal readers 
    Release lock 

독자 (들)에 대한 프로그램의 흐름은 다음과 같아야합니다

# Initial read of file contents 
    Obtain lock 
     Read file 
    Release lock 

    # Wait and respond to changes in file 
    On signal: 
     Obtain lock 
      Read file 
     Release lock  
     Do something with modified file contents 

하나가있는 경우 공유 메모리 (모든 작성자와 판독기가 액세스 할 수 있음)에있는 뮤텍스 (pthread_mutex_t) 만 있으면 충분합니다. 그렇지 않으면 rwlock (pthread_rwlock_t)을 대신 사용하는 것이 좋습니다. 대기중인 독자를 깨우려면 조건 변수 (pthread_cond_t)를 브로드 캐스팅하십시오. 물론 어려움은 공유 메모리를 설정하는 것입니다.


자문 파일 잠금 및 fanotify 인터페이스로도 충분합니다. 독자는 fanotify FAN_MODIFY 표시를 설치하고 해당 이벤트를 기다립니다. 작성자는 자문 잠금 장치 (파일이 수정되는 동안 독자가 ​​읽지 못하도록하기 위해 존재)를 사용하는 경우를 제외하고는 협력 할 필요가 없습니다.

인터페이스는 현재 무작위 CGI 프로그램이 갖고 싶지 않은 CAP_SYS_ADMIN 기능이 필요합니다.


자문 파일 잠금과 inotify 인터페이스는 충분하고, 리더 및 라이터의 양쪽 모두를 개방하고 작업의 각 세트에 대한 파일을 닫을 때 나는이에 가장 적합한을 믿습니다. 독자 (들)이 경우의 프로그램 흐름은 다음과 같습니다 작가가 잠금을 확보하지 않는 작가가 독자가 때를 알려줍니다하더라도 여전히

# Initial read of file contents 
    Open "file" for read-only 
     Obtain shared/read-lock on "file" 
      Read contents 
     Release lock 
    Close "file" 

    # Whenever wishes to modify file: 
    Open "file" for read-write 
     Obtain exclusive/write-lock 
      Modify file 
     Release lock 
    Close "file" 

입니다

Initialize inotify interface 
Add inotify watch for IN_CREATE and IN_CLOSE_WRITE for "file" 

Open "file" read-only 
    Obtain shared/read-lock 
     Read contents 
    Release lock 
Close "file" 

Loop: 
    Read events from inotify descriptor. 
    If IN_CREATE or IN_CLOSE_WRITE for "file": 
     Open "file" read-only 
      Obtain shared/read-lock 
       Read contents 
      Release lock 
     Close "file" 
     Do something with file contents 

writer가 파일을 닫습니다. 유일한 위험은 독자가 파일을 읽는 동안 다른 변경 집합이 (다른 잠금 제거 수정 자에 의해) 기록된다는 것입니다.

수정자가 파일을 새로운 것으로 바꾼다 고해도 새 파일이 준비되면 (예 : 이전 파일의 이름이 변경되거나 링크 된 경우 또는 새 파일 작성자가 파일을 닫을 때) 독자에게 올바르게 알립니다. 독자가 파일을 열어두면 파일 설명자가 마술처럼 새 파일로 이동하지 않으며 이전 (아마도 삭제 된) 내용 만 볼 수 있습니다.


는 독자와 작가가 독자는 여전히 inotify를 사용하여 파일을 닫습니다하지 않지만, 파일이 잘 리거나에 기록 될 때마다 IN_MODIFY 마크 대신에, 통지를하는 것이 중요합니다 어떤 이유로 경우. 이 경우 파일을 바꾸거나 (이름을 변경하거나 삭제하고 다시 만든 경우) 독자와 작성자가 새 파일을 볼 수는 없지만 이제는 보이지 않는 곳에서 작동한다는 것을 기억해야합니다 -filesystem 파일 내용.

독자의 프로그램 흐름 :

Initialize inotify interface 
Add inotify watch for IN_MODIFY for "file" 

Open "file" read-only 
    Obtain shared/read-lock 
     Read contents 
    Release lock 

    Loop: 
     Read events from inotify descriptor. 
     If IN_CREATE or IN_CLOSE_WRITE for "file": 
      Obtain shared/read-lock on "file" 
       Read contents 
      Release lock 
      Do something with file contents 

작가에 대한 프로그램의 흐름은 여전히 ​​거의 동일합니다

# Initial read of file contents 
    Open "file" for read-only 
     Obtain shared/read-lock on "file" 
      Read contents 
     Release lock 
    Close "file" 

    Open "file" for read-write 

    # Whenever writer wishes to modify the file: 
    Obtain exclusive/write-lock 
     Modify file 
    Release lock 

그것은 중요하다주의 할 것을 inotify를 이벤트 사실 이후에 발생한다. 일반적으로 시스템의 부하에 따라 약간의 대기 시간이 있습니다. 따라서 파일 변경에 대한 신속한 대응이 시스템이 올바르게 작동하는 데 중요하다면 대신 공유 메모리 접근 방식의 조건 변수 인 뮤텍스 또는 rwlock을 사용해야 할 수도 있습니다.

제 경험상 이러한 대기 시간은 일반적인 인간 반응 간격보다 짧습니다. 따라서 나는 인간 타임 클레스에서 충분히 빠르고 안정적인 inotify 인터페이스를 고려해야한다고 생각합니다. 밀리 초 단위와 밀리 초 단위 기계 시간 단위는 아닙니다.