문제

최근에 다음을 수행하는 스크립트를 작성해야 했습니다. os.포크() 두 개의 프로세스로 분할합니다.하위 프로세스는 서버 프로세스가 되며 다음으로 생성된 파이프를 사용하여 데이터를 상위 프로세스로 다시 전달합니다. OS.파이프().아이가 문을 닫는다 'r' 파이프의 끝과 부모가 닫힙니다. 'w' 평소처럼 파이프 끝.나는 파이프()의 반환값을 다음을 사용하여 파일 객체로 변환합니다. os.fdopen.

내가 겪고 있는 문제는 다음과 같습니다.프로세스가 성공적으로 분기되고 하위 항목이 서버가 됩니다.모든 것이 훌륭하게 작동하고 아이는 공개적으로 데이터를 성실하게 기록합니다. 'w' 파이프 끝.불행하게도 파이프의 상위 끝은 두 가지 이상한 일을 합니다:
A) 다음을 차단합니다. read() 에 대한 작업 'r' 파이프 끝.
둘째, 파이프에 저장된 데이터를 읽지 못합니다. 'w' 끝은 완전히 닫혀있습니다.

나는 즉시 버퍼링이 문제라고 생각하고 추가했습니다. 파이프.플러시() 전화를 했지만 도움이 되지 않았습니다.

쓰기 끝이 완전히 닫힐 때까지 데이터가 표시되지 않는 이유를 밝힐 수 있는 사람이 있습니까?그리고 이를 실현하기 위한 전략이 있는가? read() 비 차단에 전화 하시겠습니까?

이것은 파이프를 분기하거나 사용한 첫 번째 Python 프로그램이므로 간단한 실수를 저질렀더라도 용서해 주세요.

도움이 되었습니까?

해결책

크기를 지정하지 않고 read()를 사용하고 있습니까, 아니면 파이프를 반복자(for line in f)?그렇다면 그것이 아마도 문제의 원인일 것입니다. read()는 읽을 수 있는 내용만 읽는 것이 아니라 반환하기 전에 파일의 끝까지 읽도록 정의되어 있습니다.이는 자식이 close()를 호출할 때까지 차단된다는 의미입니다.

연결된 예제 코드에서는 괜찮습니다. 부모는 차단 방식으로 작동하고 자식을 격리 목적으로 사용하고 있습니다.계속하려면 게시한 코드에서와 같이 비차단 IO를 사용하거나(그러나 반쯤 완료된 데이터를 처리할 준비를 하십시오) 청크 단위로 읽으십시오(예: r.read(size) 또는 r.readline() ) 특정 크기/라인을 읽을 때까지만 차단됩니다.(여전히 자식에 대해 플러시를 호출해야 합니다)

파이프를 반복자로 취급하는 것은 추가 버퍼도 사용하는 것처럼 보입니다.for line in r:" 각 라인을 즉시 소비해야 하는 경우 원하는 것을 제공하지 못할 수도 있습니다.이를 비활성화하는 것이 가능할 수 있지만 fdopen의 버퍼 크기를 0으로 지정하는 것만으로는 충분하지 않은 것 같습니다.

작동해야 하는 몇 가지 샘플 코드는 다음과 같습니다.

import os, sys, time

r,w=os.pipe()
r,w=os.fdopen(r,'r',0), os.fdopen(w,'w',0)

pid = os.fork()
if pid:          # Parent
    w.close()
    while 1:
        data=r.readline()
        if not data: break
        print "parent read: " + data.strip()
else:           # Child
    r.close()
    for i in range(10):
        print >>w, "line %s" % i
        w.flush()
        time.sleep(1)

다른 팁

사용

fcntl.fcntl(readPipe, fcntl.F_SETFL, os.O_NONBLOCK)

Read ()을 호출하기 전에 두 가지 문제를 해결했습니다. read () 호출은 더 이상 차단되지 않으며 쓰기 끝에서 플러시 ()만으로 데이터가 나타납니다.

나는 당신이 I/O와 버퍼링을 차단하는 문제를 해결했다고 생각합니다.

다른 접근법을 시도하기로 결정한 경우 : 하위 프로세스는 포크 / exec 관용구의 동등한 / 대체입니다. 그것은 당신이하는 일이 아닌 것 같습니다. 당신은 단지 포크 (exec가 아님)와 두 프로세스간에 데이터를 교환합니다. multiprocessing 모듈 (Python 2.6+)이 더 잘 맞습니다.

파이썬 애플리케이션에서 포크의 "부모"대 "자식"부분은 바보입니다. 16 비트 유닉스 일의 유산입니다. 포크/exec와 exec가 작은 작은 프로세서를 최대한 활용하는 데 중요한 것들이 된 날의 영향입니다.

파이썬 코드를 부모와 자식의 두 부분으로 나눕니다.

부모 부분이 사용해야합니다 하위 프로세스 아이 부분을 실행하려면.

포크와 exec는 어딘가에 발생할 수 있지만 관리 할 필요는 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top