2013-12-20 8 views
0

대량의 데이터를 C 서브 프로세스에 매우 빠르게 쓰는 경우 브로큰 파이프 오류가 발생합니다. gpiopwm.c의 메인 루프의파이썬에서 C 서브 프로세스 : sub.stdin.write IOError 파손 파이프

process = subprocess.Popen("./gpiopwm", stdin=subprocess.PIPE) 
while True: 
    process.stdin.write("m2000\n") 
    print "bytes written" 

SECTIO :

그래서 내가 파이썬 스크립트에서 교류 하위 프로세스를 실행하고

printf("1\n"); 
while (1) { 
    fgets(input,7,stdin); // Takes input from python script 
    printf("2\n"); 

    numbers = input+1;  // stores all but first char of input 
    char first = input[0]; // stores first char of input 

    if (first=='m') { 
     printf("3\n"); 
     printf("%s\n",numbers); 
    } 
} 

그러나이의 출력은 다음과 같다 :

1 
bytes written 
Traceback (most recent call last): 
    File "serial-receive-to-pwm.py", line 20, in <module> 
    process.stdin.write("m2000\n") 
IOError: [Errno 32] Broken pipe 

C 프로그램은 분명히 fgets 줄에서로 중단됩니다 10은 절대로 인쇄되지 않습니다. 내가 잘못 했나요? 어떻게 이것을 피할 수 있습니까?

편집 : fgets 행을 역 참조 인수를 포함하지 않지만 깨진 파이프 오류가 계속 발생하도록 업데이트했습니다.

편집 : 콘솔에서 C 프로그램을 실행하려고하면 inputchar *input="m2000";

+1

'input'의 완전한 선언 (및 가능한 초기화)을 보여주십시오. –

답변

2

로 초기화되어, 당신이 충돌하는 것을 볼 수 있습니다. 디버거에서 실행하는 경우, 당신은이 라인에 있다고 볼 수 있습니다 :

그것은 input처럼 보인다
fgets(*input,7,stdin); 

는 문자 배열, 그리고 *input와 그 역 참조 당신은 당신이하지 포인터하지만 하나의 char을 통과 할 때 값. 이로 인해 정의되지 않은 동작과 충돌이 발생합니다.

오류가 아니라면 컴파일러의 경고 메시지가 표시됩니다. 경고 메시지를 무시하지 마십시오. 오류 메시지는 종종 당신이 뭔가 잘못하고 위험 할 수 있음을 나타내는 지표입니다.


일반적인 팁

: 여기처럼, 다른 프로그램에서 호출해야하는 프로그램, 테스트 프로그램을 개발할 때 먼저 작동하는지 확인합니다. 작동하지 않으면 먼저 수정하십시오.

마지막 팁 : fgets에는 대상 문자열의 개행 문자가 포함되어 있습니다. 그것을 확인하고 거기에 있다면 제거하는 것이 좋습니다. 당신은 일정한 데이터를 수정하기 위해 노력하고, 또한 당신은뿐만 아니라 데이터의 경계를 넘어 쓰고 싶은 : input의 선언을 보여주는 마지막 편집으로


, 우리는 실제 문제를 알고있다.

input을 리터럴 문자열로 가리키면 모든 리터럴 문자열은 이고 읽기 전용은이므로 리터럴 문자열을 수정할 수 없습니다. 그렇게하려고하면 정의되지 않은 동작이 발생합니다. 그것을 악화시키기 위해서, 당신의 문자열은 단지 6 자이지만, 당신은 그것에 7자를 쓰려고합니다.

먼저 변화 input 선언 및 초기화 :

char input[16] = "m2000\n"; 

이 스택에 위치하는 배열로 선언되고 그 변형 될 수있다. 그리고이 두 가지를 수행

while (fgets(input, sizeof(input), stdin) != NULL) { ... } 

할 : 우선 크기가 sizeof(input)를 사용하여, 당신은 fgets가 범위 외에 쓰기 않을 것이라는 점을 확실 할 수있다. 두 번째로, 루프 조건에서 fgets 호출을 사용하면 파이썬 스크립트가 중단 될 때 루프가 끝나게되며, 아무 것도 읽지 못하고 반복적으로 루프를 실행하지 않고 읽지 않은 데이터를 처리하지 않게됩니다.

+1

** 또한이 문제를 해결하기 위해 OP **에 ** 명시 적으로 ** ** ** 알려 주시면 () 좋지 않겠습니까? ;-) – alk

+0

나는 오류가 fgets 행에 있음을 이미 언급했다. 컴파일러는 잘 작동했지만 컴파일되지 않았을 것입니다. – theoB610

+0

@ theoB610 :'char 입력 [적어도 7];이라고 가정하자. 'fgets (input, 7, stdin);' – alk