问题集锦(21-25)

Problem 21. how to use readv() and writev() in linux platform?

Ans:

readv()and writev()称为scattered or gathered IO, 俗称向量化IO,一次可以读写多个数据块,与其他的称为线性IO不同。

 

#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;/* pointer to start of buffer */

       size_t iov_len;/* size of buffer in bytes */

};

 

1. writev( ) 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 word 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 ("buccaneer.txt", O_WRONLY | O_CREAT | O_TRUNC);

        if (fd == -1) {

                 perror ("open");

                 return 1;

        }

        /* fill out three iovec structures */

        for (i = 0; i < 3; i++) {

                 iov[i].iov_base = buf[i];

                 iov[i].iov_len = strlen (buf[i]);

        }

 /* with a single call, write them all out */

 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. readv( ) example

#include  <stdio.h>

#include  <sys/types.h>

#include  <sys/stat.h>

#include  <fcntl.h>

#include  <sys/uio.h>

int main ( )

{

        char foo[48], bar[51], baz[49];

        struct iovec iov[3];

        ssize_t nr;

        int fd, i;

        fd = open ("buccaneer.txt", O_RDONLY);

        if (fd == -1) {

                 perror ("open");

                 return 1;

        }

        /* set up our iovec structures */

  iov[0].iov_base = foo;

 iov[0].iov_len = sizeof (foo);

 iov[1].iov_base = bar;

 iov[1].iov_len = sizeof (bar);

 iov[2].iov_base = baz;

 iov[2].iov_len = sizeof (baz);

 /* read into the structures with a single call */

 nr = readv (fd, iov, 3);

 if (nr == -1) {

         perror ("readv");

         return 1;

 }

 for (i = 0; i < 3; i++)

         printf ("%d: %s", i, (char *) iov[i].iov_base);

 if (close (fd)) {

         perror ("close");

         return 1;

 }

 return 0;

}

 

PS:

Linux implements readv( ) and writev( ) as system calls, and internally performs scatter/gather I/O. In fact, all I/O inside the Linux kernel is vectored; read( ) and write( ) are implemented as vectored I/O with a vector of only one segment.一次同时读取数据块的数量以8个或少于8个时性能最佳。

 

Problem 22. how to use mmap()?

Ans:

#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;

}

PS:映射的地址空间以页边界对齐的,所以此种方法适用于大文件的映射。

 

Problem 23. How to realize thread-based asynchronous I/O?

Ans:

First, let’s look at why an application developer would want asynchronous I/O:

 • To perform I/O without blocking(性能方面的考量)

 • To separate the acts of queuing I/O, submitting I/O to the kernel, and receiving

    notification of operation completion(不同的实现方式)

开发步骤:

1. Create a pool of “worker threads” to handle all I/O.(创建工作者线程)

2. Implement a set of interfaces for placing I/O operations onto awork queue.

3. Have each of these interfaces return an I/O descriptor uniquely identifying the

  associated I/O operation. In each worker thread, grab I/O requests from the

  head of the queue and submit them, waiting for their completion.

4. Upon completion, place the results of the operation (return values, error codes,

  any read data) onto a results queue.

5. Implement a set of interfaces for retrieving status information from the results

  queue, using the originally returned I/O descriptors to identify each operation.

 

 

Problem 24 some information about vfork() and atexit()?

vfork( ) users should call _exit( ), and notexit( ), after a fork.

 

atexit( ):

#include <stdlib.h>

int atexit (void (*function)(void));

PS:

A successful invocation of atexit( ) registers the given function to run during nor-

mal process termination; i.e., when a process is terminated via either exit( ) or areturn from main( ). If a process invokes an exec function, the list of registered functions is cleared (as the functions no longer exist in the new process’ address space). Ifa process terminates via a signal, the registered functions are not called.

Registered functions must not call exit( ), lest they begin an endless recursion

#include <stdio.h>

#include <stdlib.h>

void out (void)

{

       printf ("atexit( ) succeeded!/n");

}

int main (void)

{

       if (atexit (out))

               fprintf(stderr, "atexit( ) failed!/n");

       return 0;

}

 

on_exit( ):

#include <stdlib.h>

int on_exit (void (*function)(int , void *), void *arg);

 

Problem 25 how to check a null string or empty string in C?

Ans:

char *str;

//判断字符串非空或长度不为零

if(str == NULL || str[0] == ‘/0’)

{

   return BAD_PARAMETER

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值