ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C/C++ pread(), pwrite()
    C,C++ & Linux 2020. 5. 14. 23:37
    728x90

    pread(2), pwrite(2) 함수 기능

    read(), wrte() 함수와 lseek() 함수의 결합으로, seek offset 을 이동시킨 뒤 read() or write() 합니다.

    pread(), pwrite() 함수는 lseek() 과 read() or write() 를 원자적(atomic)으로 처리합니다.

    원자적이라 함은 한 번 호출되면 반드시 모든 연산을 마친다는 뜻입니다.

    다른 프로세스나 스레드로부터 서로 연산이 분리되지 않는다는 것을 말합니다.

     

    lseek() + read() 을 하게 되면 lseek() 이후 프로세스 스케줄링으로 인해 다른 스레드로 컨트롤이 넘어가서 해당 파일의 seek offset 을 훼손시킬 수 있습니다. 그리고 다시 원래 스레드로 돌아와 read() 하게 되면 엉뚱한 영역을 읽게 될것입니다.

     

    하지만 pread() 를 하게 되면 lseek() + read() 가 원자적으로 처리되기 때문에 lseek() + read() 가 모두 처리되고 프로세스 스케줄링되는 것을 보장합니다.

     

    pread(), pwrite() 는 seek offset 을 건드리지 않습니다.

    따라서 함수 호출 뒤에도 seek offset 은 변하지 않습니다.

    함수 원형

    #include <unistd.h>
    #include <sys/types.h>
    
    ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset);
    ssize_t pwrite(int fd, const void *buf, size_t nbytes, off_t offset);

    매개변수

    fd

    읽거나 쓰고자 하는 파일 디스크립터

     

    buf

    데이터를 저장하는 버퍼

     

    nbytes

    읽거나 쓰고자 하는 데이터의 크기

     

    offset

    읽거나 쓰고자 하는 seek offset

    이 때 offset은 항상 SEEK_SET을 기준으로 합니다.

    반환값

    성공 시 읽거나 쓴 데이터의 크기, 에러 시 -1 을 리턴하고 errno 설정

    예제

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h> // for open
    #include <sys/types.h>
    #include <sys/stat.h>
    
    
    int main(int argc, char *argv[]) {
        char *filename = "ssu_test.txt";
        char buf[10];
        int fd;
        int length;
    
        fd = open(filename, O_RDONLY);
    	
    	// lseek(fd, 5, SEEK_SET) + read()
        length = pread(fd, buf, sizeof(buf), 5);
        write(1, buf, length);
        printf("\n");
    
    	// lseek(fd, 3, SEEK_SET) + read()
        length = pread(fd, buf, sizeof(buf), 3);
        write(1, buf, length);
        printf("\n");
    
    	// 데이터를 읽으면 0번째 글자부터 읽게됨
    	// 즉 pread, pwrite는 seek offset을 변화시키지 않음
        length = read(fd, buf, sizeof(buf));
        write(1, buf, length);
        printf("\n-----------------------\n");
    
    	// lseek(fd, 5, SEEK_SET) + read()
        length = pread(fd, buf, sizeof(buf), 5);
        write(1, buf, length);
        printf("\n");
    
    	// lseek(fd, 3, SEEK_SET) + read()
        length = pread(fd, buf, sizeof(buf), 3);
        write(1, buf, length);
        printf("\n");
    
        exit(0);
    }
    

    결과

     

     

     

     

     

     

     

     

     

     

    리눅스시스템프로그래밍 저자 : 홍지만
    https://book.naver.com/bookdb/book_detail.nhn?bid=14623672

    책에 기술된 예제 프로그램입니다. 책 내부에는 훨씬 더 많은 자료가 있습니다. (개인적으로 좋았습니다.)

    'C,C++ & Linux' 카테고리의 다른 글

    C/C++ dup2()  (0) 2020.05.16
    C/C++ dup()  (0) 2020.05.16
    C/C++ write()  (0) 2020.05.14
    C/C++ close() 함수  (0) 2020.05.14
    C/C++ read 함수 - 파일을 읽는 함수  (0) 2020.04.22

    댓글

Designed by Tistory.