2010-08-12 4 views
9

그때 파이프로부터 판독 및 C 코드의 다음 비트가 차단해야했지만 그것은 결코 블록라는 파이프

int pipe_fd; 
int res; 
int open_mode = O_RDONLY; 
char buf[100]; 
int bytes_read = 0; 

memset (buf, '\0', sizeof(buf)); 
pipe_fd = open(FIFO_NAME, open_mode); 

if (access(FIFO_NAME, F_OK) == -1) 
{ 
    res = mkfifo(FIFO_NAME, 0777); 
    if (res != 0) 
    { 
      fprintf (stderr, "Could not create fifo %s\n", FIFO_NAME); 
      exit (EXIT_FAILURE); 
    } 
} 

for(;;) 
{   
    do  
    {  
     res = read(pipe_fd, buf, sizeof(buf)); 
     bytes_read += res; 
    }while (res > 0); 

    // process data then go back and block 
    ............ 
} 

그것이 배시 스크립트 일부 코드가 간단한 버퍼 전송 될 때 차단하지 읽기 이 './test 1'처럼

#!/bin/bash 

pipe=/tmp/pipe 

if [[ ! -p $pipe ]]; then 
    echo "Reader not running" 
    exit 1 
fi 

if [[ "$1" ]]; then 
    echo "some string" >$pipe 
else 
    echo "q" >$pipe 
fi 

나는 GDB에서 C 코드 프로그램을 실행하고 처음에는 읽기에 차단 않지만 곧 내가 어떤 C 코드의 블록이 bash는 스크립트를 호출하지 않기 때문에, 성공적 수행 에서 버퍼를 읽은 다음 읽을 때마다 0 바이트가 읽혀집니다. 왜 더 이상 차단하지 않는지 확실하지 않습니다. '일부 문자열'데이터가 다른 쪽에서 올바르게 수신되었습니다.

나는 그냥 데이터 처리를 위해 대기 앉아서 다시 가서 가능한 한 빨리

답변

14

내가 GDB에서 C 코드 프로그램을 실행 이상 기다려야하고 처음에는 읽기에 블록을 수행하지만, 필요 나는 bash 스크립트를 더 이상 블록킹하지 않는 C 코드를 호출한다. 버퍼로부터 데이터를 성공적으로 읽은 다음 읽을 때마다 0 바이트가 읽혀 지므로 더 이상 블록킹되지 않는 이유가 확실하지 않다. '일부 문자열'데이터가 다른 쪽에서 올바르게 수신되었습니다.

0은 EOF를 의미합니다. FIFO는 읽기 및 쓰기 모두에 연결된 프로세스가있는 경우에만 읽거나 쓸 수 있습니다. 더 이상 작성자가 없으면 (셸 스크립트가 종료 됨) 독자에게 read()을 통해 EOF를 반환한다는 알림이 전송됩니다. read()가 EOF 반환하지 않을 경우

FIFO를 쉘 파이프 로직 예컨대 :

$ mkfifo ./tmp1 
$ cat <input> ./tmp1 & 
$ cat <./tmp1> /dev/null 

와 호환되도록 그런 식으로 행동, 두 번째 cat 영원히 차단하는 것입니다.

나는 그냥 데이터 처리를 위해 대기 앉아서 다시 가서 read()는 EOF 처음으로 반환 된 후 open()는 FIFO를 다시해야 당신의 C 프로그램에서 더

기다릴 필요가

.

P. 귀하의 웹 사이트에 quite nice FIFO summary이 있습니다. 두 번째 페이지의 표를 확인하십시오. 는 C는 "EOF"조건

+0

많은 감사, 그것을 깨닫지 못했습니다. 다시 열기 전에 FIFO를 닫아야합니까 – tech74

+0

@ tech74 : 분명히. 'open()'은 새로운 파일 기술자를 할당합니다 - 이전의 파일 기술자는'close()'를 사용하여 해제해야합니다. 기록기는 다시 읽기 위해 FIFO를 다시 열 때까지 차단됩니다. – Dummy00001

+1

+1 링크! –

0

배시 스크립트는 파이프를 닫습니다.

따라서 쓰기 스크립트는 파이프를 열고 반복적으로 설명 된 디스크립터를 사용하여 무언가를 작성하고 마지막에 덮어 쓰기 된 디스크립터를 닫아야합니다.

0

내가 생각 쓰기 측 쉘 스크립트가 파이프마다 시간을 닫을 때 에코 뭔가를지고 있으므로