일반 파일 작업 (파이프 와 소켓 포함)

Table of Contents
2.1. 여러 개의 연결 을 어떻게 관리 합 니까?
2.2. 나 는 어떻게 해야만 상대방 과 의 연결 이 중지 되 었 다 는 것 을 알 수 있 습 니까?
2.3. 디 렉 터 리 를 읽 는 가장 좋 은 방법 은 무엇 입 니까?
2.4. 다른 프로 세 스에 서 파일 이 열 리 는 것 을 어떻게 알 수 있 습 니까?
2.5. 나 는 어떻게 서 류 를 잠 갑 니까?
2.6. 다른 프로 세 스 가 파일 을 업데이트 한 것 을 어떻게 발견 할 수 있 습 니까?
2.7. du 는 어떻게 일 합 니까?
2.8. 나 는 어떻게 파일 의 길 이 를 얻 습 니까?
2.9. 나 는 어떻게 셸 처럼 파일 이름 의 '~' 을 확장 합 니까?
2.10. 유명한 파이프 (FIFO) 는 무엇 을 할 수 있 습 니까?
소켓 FAQhttp://www.lcg.org/sock-faq/
2.1. 여러 개의 연결 을 어떻게 관리 합 니까?
"하나 이상 의 파일 설명자 (fd)/연결 (connection)/흐름 (stream) 을 동시에 감시 하려 면 어떻게 해 야 합 니까?"
select () 또는 poll () 함 수 를 사용 합 니 다.
메모: select () 는 BSD 에 도입 되 었 고, poll () 은 SysV STREAM 흐름 제어 의 산물 입 니 다.따라서 여기 서 플랫폼 이식 에 대한 고려 가 있 습 니 다. 순수한 BSD 시스템 은 poll () 이 부족 할 수도 있 고 빠 른 SVR 3 시스템 에는 select () 가 없 을 수도 있 습 니 다. SVR 4 에 가입 하 더 라 도.현재 두 가 지 는 모두 POSIX. 1g 기준 이다.
select () 와 poll () 은 본질 적 으로 같은 일 을 하 는데 완성 하 는 방법 만 다르다.둘 다 파일 설명 자 를 검사 함으로써 특정한 시간 이 위 에서 발생 하고 일정한 시간 내 에 발생 할 지 여 부 를 검사 합 니 다.
[중요 한 사항: select () 든 poll () 이 든 일반 파일 에 큰 효 과 를 내지 않 습 니 다. 인터페이스 (socket), 파이프 (pipe), 위조 단말기 (pty), 단말기 (tty) 와 다른 일부 문자 장치 에 중심 을 두 지만 이 조작 들 은 모두 시스템 관련 (system - dependent) 입 니 다.]
2.1.1. 저 는 select () 함 수 를 어떻게 사용 합 니까?
select () 함수 의 인 터 페 이 스 는 주로 'fd' 라 고 합 니 다.set '유형의 기초 위.그것 ('fd set') 은 파일 설명자 (fd) 의 집합 입 니 다.fd 때문에set 형식의 길 이 는 서로 다른 플랫폼 에서 다 르 기 때문에 표준 매크로 정의 로 이러한 변 수 를 처리 해 야 합 니 다.
    fd_set set;
    FD_ZERO(&set);       /*  set   */
    FD_SET(fd, &set);    /*  fd  set */
    FD_CLR(fd, &set);    /*  fd set    */
    FD_ISSET(fd, &set);  /*   fd set    */
      

과거 에 fdset 는 보통 32 개 이상 의 파일 설명자 만 포함 할 수 있 습 니 다. 왜냐하면 fdset 는 사실 하나의 int 비트 벡터 로 만 이 루어 집 니 다. 대부분의 경우 fd 를 검사 합 니 다.set 임의의 값 을 포함 할 수 있 는 파일 설명 자 는 시스템 의 책임 이지 만 fd 를 확인 합 니 다.set 얼마나 넣 을 수 있 는 지SETSIZE 의 값 입 니 다. *이 값 은 시스템 과 관련 된 * 이 며, 시스템 의 select () man 매 뉴 얼 을 검사 합 니 다.1024 개 이상 의 파일 설명자 에 대한 시스템 지원 에 문제 가 있 습 니 다.[번역자 주: 리 눅 스 는 바로 이런 시스템 입 니 다! sizeof (fd set) 의 결 과 는 128 (* 8 = FD SETSIZE = 1024) 입 니 다. 비록 이런 상황 을 겪 는 경 우 는 드 물 지만.]
select 의 기본 인 터 페 이 스 는 매우 간단 하 다.
    int select(int nfds, fd_set *readset, fd_set *writeset,
               fd_set *exceptset, struct timeval *timeout);
      

그 중:
nfds     
                 ,        fd_set    
       ,             。
readset    
                    。
writeset
                    。
exceptset
                   。( :         )
timeout
     NULL        ,     timeval     ,   
          。(    tv_sec tv_usec   0,       
            ,       )
      

함 수 는 응답 작업 에 대응 하 는 작업 파일 설명자 의 총 수 를 되 돌려 주 고 세 그룹의 데 이 터 는 모두 적당 한 위치 에서 수정 되 며 응답 작업 의 일부 만 수정 되 지 않 습 니 다.이어서 FDISSET 매크로 는 되 돌아 오 는 파일 설명자 그룹 을 찾 습 니 다.
단일 파일 설명자 의 가 독성 을 간단하게 테스트 하 는 예 입 니 다.
     int isready(int fd)
     {
         int rc;
         fd_set fds;
         struct timeval tv;
    
         FD_ZERO(&fds);
         FD_SET(fd,&fds);
         tv.tv_sec = tv.tv_usec = 0;
    
	 rc = select(fd+1, &fds, NULL, NULL, &tv);
         if (rc < 0)
           return -1;
    
         return FD_ISSET(fd,&fds) ? 1 : 0;
     }
      

물론 우리 가 NULL 지침 을 fd 로 한다 면set 가 들 어 오 면 이러한 작업 의 발생 에 관심 이 없다 는 뜻 이지 만 select () 는 발생 하거나 대기 시간 을 초과 할 때 까지 기 다 립 니 다.
[번역자 주: 리 눅 스에 서 timeout 은 프로그램 이 비 sleep 상태 에서 보 내 는 시간 을 가리 키 며, 실제 과거의 시간 이 아니 라 비 리 눅 스 플랫폼 이식 의 시간 과 다른 문 제 를 일 으 킬 수 있다. 이식 문 제 는 System V 스타일 에서 select () 도 포함한다.함수 가 종료 되 기 전에 timeout 을 정의 되 지 않 은 NULL 상태 로 설정 합 니 다. BSD 에 서 는 그렇지 않 습 니 다. Linux 는 이 점 에서 System V 를 따 르 기 때문에 timeout 지침 을 중복 이용 하 는 데 도 주의해 야 합 니 다.]
2.1.2. 나 는 어떻게 poll () 을 사용 합 니까?
poll () 은 테스트 하고 싶 은 파일 설명자 와 이 벤트 를 포함 하 는 지향 구조 'struct pollfd' 목록 의 지침 을 받 습 니 다.이 벤트 는 구조 에서 이벤트 필드 의 비트 마스크 로 확 정 됩 니 다.현재 구 조 는 호출 후 작성 되 고 이벤트 가 발생 한 후에 돌아 갑 니 다.SVR 4 (더 빠 를 수 있 는 버 전) 의 "poll. h"파일 에는 이벤트 확인 에 사용 할 매크로 정의 가 포함 되 어 있 습 니 다.이벤트 의 대기 시간 은 밀리초 까지 정확 합 니 다.다음은 pollfd 의 구조 입 니 다.
     struct pollfd {
         int fd;        /*       */
         short events;  /*       */
         short revents; /*          */
     };
      

select () 와 매우 비슷 합 니 다. 정상 값 으로 돌아 갈 때 이벤트 에 응답 하 는 파일 설명자 의 개 수 를 만족 시 키 는 것 을 의미 합 니 다. 0 으로 돌아 가면 규정된 이벤트 에서 사건 이 발생 하지 않 았 음 을 의미 합 니 다.마이너스 로 돌아 가 는 것 을 발견 하면 errno 를 즉시 확인 해 야 합 니 다. 오류 가 발생 했 기 때 문 입 니 다.
사건 이 일어나 지 않 으 면 revents 가 비 워 지기 때문에 쓸데없는 짓 을 할 필요 가 없다.
여기 가 하나의 예 이다.
   /*          ,             。      
                     handler(),       ,  
                。*/
   
   #include <stdlib.h>
   #include <stdio.h>
  
   #include <sys/types.h>
   #include <stropts.h>
   #include <poll.h>
  
   #include <unistd.h>
   #include <errno.h>
   #include <string.h>
  
   #define NORMAL_DATA 1
   #define HIPRI_DATA 2
  
   int poll_two_normal(int fd1,int fd2)
   {
       struct pollfd poll_list[2];
       int retval;
  
       poll_list[0].fd = fd1;
       poll_list[1].fd = fd2;
       poll_list[0].events = POLLIN|POLLPRI;
       poll_list[1].events = POLLIN|POLLPRI;
  
       while(1)
       {
           retval = poll(poll_list,(unsigned long)2,-1);
           /* retval     0  -1,           */
  
           if(retval < 0)
           {
               fprintf(stderr,"poll  : %s/n",strerror(errno));
               return -1;
           }
    
           if(((poll_list[0].revents&POLLHUP) == POLLHUP) ||
              ((poll_list[0].revents&POLLERR) == POLLERR) ||
              ((poll_list[0].revents&POLLNVAL) == POLLNVAL) ||
              ((poll_list[1].revents&POLLHUP) == POLLHUP) ||
              ((poll_list[1].revents&POLLERR) == POLLERR) ||
              ((poll_list[1].revents&POLLNVAL) == POLLNVAL))
             return 0;
  
           if((poll_list[0].revents&POLLIN) == POLLIN)
             handle(poll_list[0].fd,NORMAL_DATA);
           if((poll_list[0].revents&POLLPRI) == POLLPRI)
             handle(poll_list[0].fd,HIPRI_DATA);
           if((poll_list[1].revents&POLLIN) == POLLIN)
             handle(poll_list[1].fd,NORMAL_DATA);
           if((poll_list[1].revents&POLLPRI) == POLLPRI)
             handle(poll_list[1].fd,HIPRI_DATA);
       }
   }
      

2.1.3. SysV IPC 와 select ()/poll () 을 동시에 사용 할 수 있 습 니까?
* 안 돼 요.(AIX 를 제외 하고 이상 한 방법 으로 이 조합 을 실현 하기 때문이다)
일반적으로 select () 나 poll () 과 SysV 메시지 큐 를 동시에 사용 하면 많은 번 거 로 움 을 가 져 올 수 있 습 니 다.SysV IPC 의 대상 은 파일 설명자 로 처리 되 지 않 기 때문에 select () 와 poll () 에 전 달 될 수 없습니다.여기 에는 몇 가지 해결 방법 이 있 는데 그 거 친 정 도 는 각각 다르다.
 
  • SysV IPC 사용 을 완전히 포기 합 니 다.: -)
  • fork () 를 사용 한 다음 에 하위 프로 세 스 로 SysV IPC 를 처리 한 다음 에 파이프 나 인터페이스 로 부모 프로 세 스 와 이야기 합 니 다.부모 프로 세 스 는 select () 를 사용 합 니 다.
  • 위 와 같 지만 하위 프로 세 스 를 select () 로 사용 하고 아버지 와 메시지 대기 열 로 교류 합 니 다.
  • 프로 세 스 를 배정 하여 메 시 지 를 보 낸 후에 신 호 를 보 냅 니 다. *경고 *: 이 건 쉽 지 않 습 니 다. 메 시 지 를 잃 어 버 리 거나 잠 금 을 일 으 킬 수 있 는 프로그램 을 쉽게 작성 할 수 있 습 니 다.

  • 또 다른 방법 이 있다.

    좋은 웹페이지 즐겨찾기