2014-05-17 2 views
3

man 2 select 상태는 버그에서 다음블록을 읽을 수 있지만 파이프에 블록을 쓸 수 있습니까?

리눅스에서

선택() 반면, 그럼에도 불구하고 후속 읽기 블록을 " 독서에 대한 준비"로 소켓 파일 디스크립터를보고 할 수 있습니다. 이것은 데이터가 도착했지만 검사시에 체크섬이 잘못되어 폐기 될 때 예제가 발생하여 일 수 있습니다. 파일 설명자가 준비 상태로 위장적으로보고되는 다른 상황이있을 수 있습니다. 따라서 차단해서는 안되는 소켓에 O_NONBLOCK을 사용하는 것이 더 안전 할 수 있습니다.

따라서 내 read 호출은 차단하지 않아야하고 따라서 파이프 파일 설명자 O_NONBLOCK을 표시해야합니다. 그러나 데이터를 파이프에 쓸 때까지 write 호출을 차단하고 싶습니다.

파이프에 데이터를 쓸 때 write 블록을 차단할 수 있습니까? 그렇지만 read 읽기 끝을 차단하지 않습니까? 예를 들어 fcntl을 파이프가 생성 된 후에 한 쪽에서 만 호출하는 것은 합당한가? 왜냐하면 읽기 및 쓰기 끝에 별도의 파일 설명자가 있기 때문입니까?

답변

1

write 앞에 fcntl으로 O_NONBLOCK 플래그를 제거하고 write 완료 후에 다시 넣을 수 있습니다. 그러나 항상 소켓을 비 블로킹 상태로 유지하고 완료 될 때까지 write을 루프에 넣는 것이 좋습니다. CPU에 과부하가 걸리지 않게하려면 소켓을 쓸 준비가 될 때까지 프로세스를 차단할 select를 넣으십시오.

int blockingWriteOnNonBlockingFd(int fd, char *buf, int size) { 
    fd_set wset, w; 
    int n, r; 
    FD_ZERO(&wset); 
    FD_SET(fd, &wset); 
    n = 0; 
    while (n < size) { 
    w = wset; 
    select(fd+1, NULL, &w, NULL, NULL); 
    r = write(fd, buf+n, size-n); 
    if (r <= 0) { 
     if (r<0 && (errno == EWOULDBLOCK || errno == EAGAIN)) r = 0; 
     else { /* broken connection */ break; } 
    } 
    n += r; 
    } 
    return(n); 
} 
+0

나는 비 블로킹에 FD를 차단하고 읽기에 쓰기 FD를 설정할 수들이 별도의 파일 기술자 파이프를 사용하고 있기 때문에, : 같은

그래서, 코드를 작성 보일 것인가? – Flash

+0

예, 가능합니다. 아마 원래의 질문을 잘못 이해했을 것입니다. 비록 같은 소켓에서 읽고 쓰고 싶었지만. – Marian

관련 문제