2017-05-08 3 views
10

제가 쓰고있는 프로그램은 프로세스 간 통신을 위해 Linux에서 FIFO 파이프를 사용하고 있습니다. 그것은 오히려 잘 해킹이지만, 상관없이 나는 문제가 있습니다.명명 된 파이프로 StreamWriter를 열려고하면 모노가 중단됩니다.

 if (!File.Exists(Path.GetTempPath() + "gminput.pipe")) 
     { 
      ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = "/usr/bin/mkfifo", Arguments = Path.GetTempPath() + "gminput.pipe", }; 
      Process proc = new Process() { StartInfo = startInfo, }; 
      proc.Start(); 
      proc.WaitForExit(); 
     } 
     if (!File.Exists(Path.GetTempPath() + "gmoutput.pipe")) 
     { 
      ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = "/usr/bin/mkfifo", Arguments = Path.GetTempPath() + "gmoutput.pipe", }; 
      Process proc = new Process() { StartInfo = startInfo, }; 
      proc.Start(); 
      proc.WaitForExit(); 
     } 

     using (StreamWriter outputPipe = new StreamWriter(Path.GetTempPath() + "gmoutput.pipe")) 
     using (StreamReader inputPipe = new StreamReader(Path.GetTempPath() + "gminput.pipe")) 
     { 
      Console.WriteLine("This code is never reached!"); 
     } 

파이프가 이미 있는지 확인하고 그렇지 않으면 mkfifo를 호출하여 파이프를 만듭니다. 이 부분은 제대로 작동하는 것, 명명 된 파이프 올바르게 만들어집니다. StreamWriter, StreamReader 또는 둘 모두를 사용하여 열려고 할 때마다 프로그램이 중단됩니다. 오류 또는 아무것도. 디버거에서도 멈 춥니 다.

가장 좋은 부분은 ... 작동하는 데 사용되었습니다. 나는 프로세스 간 의사 소통이 작동했다. 그리고 나서 그것은 단지 설명 할 수 없게 멈췄다. 나는 여기서 본 것을 제외한 모든 것을 주석 처리하고, 내 시스템을 재시작하고, 파이프 등을 재사용했다. 뭐라 구요? 내 코드에 문제가 있습니까? 아니면 시스템의 다른 부분이 간섭합니까?

+6

도움이 될지 모르겠지만 경로를 연결 한 과거에는 문제가있었습니다. 어느 날 그것이 효과가 있었고, 다음은 그렇지 않았습니다! 나를위한 솔루션 Path.Combine (...) 경로를 사용하여이 일관성없는 동작을 중지했습니다. –

답변

3

이것은 의도적으로 설계된 동작입니다. 다음을 시도해보십시오 : bash 터미널을 2 개 열고 파이프를 만든 다음 터미널 중 하나에서 그것을 읽고 다른 터미널에서 씁니다.

>mkfifo test.fifo 
>echo "test" > test.fifo 

>cat test.fifo 
예를

를 들어 당신이 상관없이 순서가 각면 블록이 다른 쪽을 기다리는 것을 볼 수 있습니다.

프로세스 1의 입력 파이프는 프로세스 2의 출력 파이프이고 그 반대의 경우도 마찬가지입니다. 두 프로세스가 동일한 코드를 사용하여 파이프에 액세스하면 프로세스 1은 입력 파이프를 읽고 프로세스 2가 무언가를 쓰는 것을 기다립니다. 또한 프로세스 2는 입력 파이프를 읽고 프로세스 1이 쓰기를 기다리지 만 프로세스 1은 대기 중이며 다른 파이프를 열지도 않았습니다. Gridlock.

이 문제를 해결할 수있는 한 가지 방법은 독자 또는 작성자를 별도의 스레드에서 실행하는 것입니다. 그런 식으로 과정 1 & 2 두 파이프를 열면 그리드 록이 해결됩니다.

다른 옵션은 파이프를 비동기 적으로 여는 것입니다. 내 C#을 녹슨이지만, 많은 예에 유래에있다 :

How to do a non-waiting write on a named pipe (c#)?

NamedPipeServerStream in Mono

은 기본적으로 리더/라이터에 NamedPipeServerStream를 전달합니다.

나는 P1이 Reader를 연 다음 Writer를 열었 기 때문에 P2가 Writer를 연 다음 Reader가 P1을 차단 해제했기 때문에 이전과는 다른 것으로 생각됩니다.

관련 문제