Linux System Programming note 4 —— Advanced File I/O

来源:互联网 发布:三笠宫崇仁亲王知乎 编辑:程序博客网 时间:2024/06/03 21:14
1. Scatter/Gather I/O(vectored I/O)
#include <sys/uio.h>

ssize_t readv (int fd,
                    const struct iovec *iov,
                    int count);

ssize_t writev (int fd,
                     const struct iovec *iov,
                     int count);

struct iovec {
     void *iov_base;
     size_t iov_len;
};


example:


#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <sys/uio.h>int main(){     struct iovec iov[3];     ssize_t nr;     int fd, i;     char *buf[] = {          "The term buccaneer comes from the world boucan.\n",          "A boucan is a wooden frame used for cooking meat.\n",          "Buccaneer is the West Indies name for a pirate.\n"     };     fd = open("buccaner.txt", O_WRONLY | O_CREAT | O_TRUNC);     if (fd == -1){          perror("open");          return 1;     }     for (i = 0; i < 3; i++){          iov[i].iov_base = buf[i];          iov[i].iov_len = strlen(buf[i]) + 1;     }     nr = writev(fd, iov, 3);     if (nr == -1){          perror("writev");          return 1;     }     printf("wrote %d bytes\n", nr);     if (close(fd)){          perror("close");          return 1;     }     return 0;}


2. Creating a New Epoll Instance
#include <sys/epoll.h>

int epoll_create1(int flags); // Only EPOLL_CLOEXEC is a valid flag.

errno:
EINVAL: Invalid flags parameter
EMFILE: The user has reached limit on the total number of open files.
ENFILE: The system has reached its limit on the total number of open files.
ENOMEM: Insufficient memory was available to complete the operation.

3. Controlling Epoll
#include <sys/epoll.h>

int epoll_ctl(int epfd,
                 int op,
                 int fd,
                 struct epoll_event *event);

op: EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD


struct epoll_event{
     _u32 events;
     union {
          void *ptr;
          int fd;
          __u32 u32;
          __u64 u64;
     } data;
};

events:
EPOLLERR, EPOLLET, EPOLLHUP, EPOLLIN, EPOLLONESHOT, EPOLLOUT, EPOLLPRI

4. Waiting for Events with Epoll
#include <sys/epoll.h>

int epoll_wait(int epfd,
                    struct epoll_event *events,
                    int maxevents,
                    int timeout);

5. mmap()
#include <sys/mman.h>

void *mmap (void *addr,
                   size_t len,
                   int prot,
                   int flags,
                   int fd,
                   off_t offset);


prot: PROT_READ, PROT_WRITE, PROT_EXEC
flags:MAP_FIXED, MAP_PRIVATE, MAP_SHARED

6. The page size
#include <unistd.h>

long sysconf(int name); // best bet for portability and future compatility
long page_size = sysconf(_SC_PAGESIZE);

#include <unistd.h>

int getpagesize(void); // was dropped from the 1003.1-2001 revision of the POSIX standard.

#include <sys/usr.h>

int page_size = PAGE_SIZE;

SIGBUS 
This signal is generated when a process attempts to access a region of a mapping that is no longer valid--for example, because the file was truncated after it was mmaped.
SIGSEGV
This signal is generated when a process attempts to write to a region that is mapped read-only.

7. munmap()
#include <sys/mman.h>

int munmap (void *addr, size_t len);

Example: (of map)
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <sys/mman.h>int main(int argc, char *argv[]){     struct stat sb;     off_t len;     char *p;     int fd;     if (argc < 2) {          fprintf(stderr, "usage: %s <file>\n", argv[0]);          return 1;     }     fd = open(argv[1], O_RDONLY);     if (fd == -1){          perror("open");          return 1;     }     if (fstat(fd, &sb) == -1){          perror("fstat");          return 1;     }     if (!S_ISREG (sb.st_mode)){          fprintf(stderr, "%s is not a file\n", argv[1]);          return 1;     }     p = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);     if (p == MAP_FAILED){          perror ("mmap");          return 1;     }     if (close(fd) == -1){          perror("close");          return 1;     }     for (len = 0; len < sb.st_size; len++){          putchar (p[len]);     }     if (munmap (p, sb.st_size) == -1){          perror("munmap");          return 1;     }     return 0;}


8. Resizing a Mapping
#define  _GNU_SOURCE
#include <sys/mman.h>

void * mremap(void *addr, size_t old_size, size_t new_size, unsigned long flags);

flags: 0 or MREMAP_MAYMOVE

9. Changing the protection of a Mapping
#include <sys/mman.h>

int mprotect (const void *addr, size_t len, int prot);

10. Synchronizing File with a Mapping
#include <sys/mman.h>

int msync (void *addr, size_t len, int flags);
flags:
MS_SYNC:
     The sync() call will not return until all pages are written back to disk.
MS_ASYNC:
     The sync() call returns immediately without waiting for the writes to take place.
MS_INVALIDATE:
     Specifies that all other cached copies of the mapping be invalidated.

11. Giving Advice on a Mapping

#include <sys/mman.h>

int madvise (void *addr, size_t len, int advice);

advice:
MADV_NORMAL
MADV_RANDOM
MADV_SEQENTIAL
MADV_WILLNEED
MADV_DONTNEED
MADV_DONTFORK
MADV_DOFORK+

12. The posix_fadvise() System Call
#include <fcntl.h>

int posix_fadvise(int fd,
                        off_t offset,
                        off_t len,
                        int advice);

advice:
POSIX_FADV_NORMAL
POSIX_FADV_RANDOM
POSIX_FADV_SEQUENTIAL
POSIX_FADV_WILLNEED
POSIX_FADV_NOREUSE
POSIX_FADV_DONTNEED

13. The readhead() System Call

#define _GNU_SOURCE

#include <fcntl.h>

ssize_t readhead(int fd,
                         off64_t offset,
                         size_t count);

14. Asynchronous I/O

#include <aio.h>

/* asynchronous I/O control block */
struct aiocb {
     int aio_fildes;
     int aio_lio_opcode;
     int aio_reqprio;
     volatile void *aio_buf;
     size_t aio_nbytes;
     struct sigevent aio_sigevent;

     /* internal, private members follow... */
};

int aio_read(struct aiocb *aiocbp);
int aio_write(struct aiocb *aiocbp);
int aio_error(const struct aiocbp *aiocbp);
int aio_return(struct aiocb *aiocbp);
int aio_cancel(int fd, struct aiocb *aiocbp);
int aio_fsync(int op, struct aiocb *aiocbp);
int aio_suspend(const struct aiocb * const cblist[],
                       int n,
                       const struct timespec *timeout);



0 0
原创粉丝点击