2014年4月25日 星期五

read,write vs fread, fwrite

The read() and write() are blocking I/O, If your source use the system function read() or write() to access the filesystem that they will actually launch the io system call.

The fread() and fwrite() are user-buffered I/O. The data will keep in the buffer until the data size is filled with the block size then they will launch the real io system call

Experiment with Blocking I/O
write.c
--
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int fd;
    int i;
    char c = 'a';

    fd = open("data.xxx", O_CREAT | O_WRONLY | O_TRUNC);

    for(i = 0; i < 4096; ++i)
        write(fd, &c, 1);

    close(fd);
}

strace -c -e trace=write ./write
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.012361           3      4096           write
------ ----------- ----------- --------- --------- ----------------
100.00    0.012361                  4096           total

read.c
--
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int fd;
    int i;
    char c = 'a';

    fd = open("data.xxx",  O_RDONLY);

    while(read(fd, &c, 1));

    close(fd);

}

strace -c -e trace=read ./read
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.020256           5      4098           read
------ ----------- ----------- --------- --------- ----------------
100.00    0.020256                  4098           total


User-Buffered IO
fwrite.c
--
#include <stdlib.h>
#include <stdio.h>

int main()
{
    FILE *fp;
    int i;
    char c = 'a';

    fp = fopen("data.xxx", "w");

    for(i = 0; i < 4096; ++i)
        fwrite(&c, 1, 1, fp);

    fclose(fp);
}

strace -c -e trace=write ./fwrite
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.000004           4         1           write
------ ----------- ----------- --------- --------- ----------------
100.00    0.000004                     1           total

#include <stdlib.h>
#include <stdio.h>

int main()
{
    FILE *fp;
    int i;
    char c = 'a';

    fp = fopen("data.xxx", "r");

    while(fread(&c, 1, 1, fp));

    fclose(fp);
}

strace -c -e trace=read ./fread
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.000009           3         3           read
------ ----------- ----------- --------- --------- ----------------
100.00    0.000009                     3           total

2014年4月22日 星期二

Linux PIP wirte and read

By the linux implementaion, the WRITE PROCESS can write max data into the PIP is 64Kbytes if there are no process reads(consumes) data from the PIP then the WRITE PROCESS will block in write(), after the READ PROCESS reads(consumes) data more than 4KBytes from PIP then the WRITE PROCESS will wirte data into the PIP again to fill the data consumed by READ  PROCESS, else the WRITE PRCESS still block in wirte() if the READ PROCESS reads(consumes) data less than 4KBytes.


Ex:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>


int main()
{
   pid_t pid;
   int pipfd[2] = {0};


   if(pipe(pipfd) < 0) {
       printf("pipe() ... fail\n");
       exit(0);
   }


   if((pid = fork()) == 0) {
       char *buf = "0123456789";
       int cnt = 1;


       close(pipfd[0]);
       while(1) {
           printf(" Write ==========> PIP: cnt:%d \n", cnt++);
           //write(pipfd[1], buf, strlen(buf));
           write(pipfd[1], buf, 1);
       }


   } else {
       char buf[512];
       int count = 1;


       sleep(30);
       close(pipfd[1]);
       while(1){
           read(pipfd[0], &buf, sizeof(buf));
           printf(" PIP ==========> Read(): cnt:%d \n", count++);
           sleep(1);
       }
   }


   return 0;

}