POSIX                
            입력 / 출력 다중화
        
        
            
    수색…
소개
 IO가 차단 / 비 차단 및 동기 / 비동기 일 수 있습니다. POSIX API는 동기식 블로킹 API (예 : 고전적인 읽기, 쓰기, 전송, recv 호출), 동기 논 블로킹 API (동일한 기능, O_NONBLOCK 플래그 및 IO 멀티플렉싱 호출로 열린 파일 설명자) 및 비동기 API ( aio_ 시작하는 함수)를 제공합니다. 
동기식 API는 일반적으로 "fd 당 하나의 스레드 / 프로세스"스타일과 함께 사용됩니다. 이것은 자원에 끔찍합니다. 비 차단 API는 한 스레드에서 fds 집합과 함께 작동 할 수 있습니다.
투표
이 예제에서 우리는 연결된 소켓 쌍을 만들고 하나에서 다른 문자열로 4 개의 문자열을 보내고받은 문자열을 콘솔에 출력합니다. 우리가 send를 호출 할 횟수는 우리가 recv를 호출 한 횟수와 같지 않을 수도 있습니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#define BUFSIZE 512
int main()
{    
    #define CKERR(msg) {if(ret < 0) { perror(msg); \
        close(sockp[0]); close(sockp[1]); exit(EXIT_FAILURE); } }
    const char* strs_to_write[] = {"hello ", "from ", "other ", "side "};
    
    int sockp[2] = {-1, -1};
    ssize_t ret = socketpair (AF_UNIX, SOCK_STREAM, 0, sockp);
    CKERR("Socket pair creation error")
    
    struct pollfd pfds[2];
    for(int i=0; i<2; ++i) {
        pfds[i] = (struct pollfd){sockp[i], POLLIN|POLLOUT, 0};
        fcntl(sockp[i], F_SETFL|O_NONBLOCK); // nonblocking fds are
                // literally mandatory for IO multiplexing; non-portable
    }
    char buf[BUFSIZE];
    
    size_t snt = 0, msgs = sizeof(strs_to_write)/sizeof(char*);
    while(1) {
        int ret = poll(pfds,
            2 /*length of pollfd array*/,
            5 /*milliseconds to wait*/);
        CKERR("Poll error")
        if (pfds[0].revents & POLLOUT && snt < msgs) {
            // Checking POLLOUT before writing to ensure there is space
            // available in socket's kernel buffer to write, otherwise we
            // may face EWOULDBLOCK / EAGAIN error
            ssize_t ret = send(sockp[0], strs_to_write[snt], strlen(strs_to_write[snt]), 0);
            if(++snt >= msgs)
                close(sockp[0]);
            CKERR("send error")
            if (ret == 0) {
                puts("Connection closed");
                break;
            }
            if (ret > 0) {
                // assuming that all bytes were written
                // if ret != %sent bytes number%, send other bytes later
            }
        }
        if (pfds[1].revents & POLLIN) {
            // There is something to read
            ssize_t ret = recv(sockp[1], buf, BUFSIZE, 0);
            CKERR("receive error")
            if (ret == 0) {
                puts("Connection closed");
                break;
            }
            if (ret > 0) {
                printf("received str: %.*s\n", (int)ret, buf);
            }
        }
    }
    close(sockp[1]);
    return EXIT_SUCCESS;
}
고르다
Select는 I / O 멀티플렉싱을 수행하는 또 다른 방법입니다. 그 중 하나는 winsock API에 존재하는 장점입니다. 게다가 리눅스에서 select ()는 sleep되지 않은 시간을 반영하여 timeout을 수정한다. 대부분의 다른 구현은 이것을하지 않습니다. (POSIX.1은 두 가지 동작 모두 허용한다.)
 폴링과 셀렉트 모두 ppoll 및 pselect 대안을 가지고있어 이벤트 대기 중에 들어오는 신호를 처리 할 수 있습니다. 그리고 둘 다 엄청난 양의 파일 디스크립터 (천 개 이상)로 인해 속도가 느려지므로 Linux에서 epoll 과 FreeBSD에서 kqueue 와 같은 특정 플랫폼 호출을 선택하는 것이 현명 할 것입니다. 또는 비동기 API (POSIX의 전환 aio 예 또는 IO 완료 포트와 같은 특정 일). 
선택 호출의 프로토 타입은 다음과 같습니다.
int select(int nfds, fd_set *readfds, fd_set *writefds,
       fd_set *exceptfds, struct timeval *timeout);
 fd_set 는 파일 디스크립터의 비트 마스크 배열이며, 
 nfds 는 set + 1에있는 모든 파일 설명자의 최대 수입니다. 
선택 작업 스 니펫 :
fd_set active_fd_set, read_fd_set;
FD_ZERO (&active_fd_set); // set fd_set to zeros
FD_SET (sock, &active_fd_set); // add sock to the set
// # define FD_SETSIZE sock + 1
while (1) {
    /* Block until input arrives on one or more active sockets. */
    read_fd_set = active_fd_set; // read_fd_set gets overriden each time
    if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) {
        // handle error
    }
    // Service all file descriptors with input pending.
    for (i = 0; i < FD_SETSIZE; ++i) {
        if (FD_ISSET (i, &read_fd_set)) {
            // there is data for i
    }
}
 대부분의 POSIX 구현에서 디스크의 파일과 연관된 파일 디스크립터가 블로킹한다는 점에 유의하십시오. 따라서 writefds 에이 파일이 설정되어 있어도 파일에 쓰는 것은 모든 바이트가 디스크에 덤프되지 않을 때까지 차단됩니다