您的位置:首页 > 运维架构 > Linux

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

2014-06-06 09:08 375 查看
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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  pthread linux programming