Linux 应用程序 之 IO编程(一)

  我的linux 环境是windows8.1 + VMware6.5.1+  Fedora14,参考书籍:第六章

      链接:Linux应用程序开发详解(1-11).pdf

 

我利用一个SSH软件SSH Secure File Transfer Client 来从Linux传输文件

技术分享

来张虚拟机运行Fedora的图:

技术分享 

 

下面步入正题:

IO最基本操作:

 

 1 //hello.c
 2 #include <unistd.h>
 3 #include <sys/types.h>
 4 #include <sys/stat.h>
 5 #include <fcntl.h>
 6 #include <stdlib.h>
 7 #include <string.h>
 8 #include <stdio.h>
 9 #define MAXSIZE
10 int main(void)
11 {
12     int i,fd,size,len;
13     char *buf ="hello! I‘m wirting to this file!";
14     char buf_r[10];
15     len= strlen(buf);
16     if((fd = open("/tmp/hello2.txt",O_CREAT |O_TRUNC | O_RDWR,0666))<0)//打开文件
17     {
18         perror("open:");
19         exit(1);
20     }else 
21     {
22      printf("open file :hello2.txt %d\n",fd);
23     }    
24     if((size =  write( fd, buf,len))<0)//写固定长度数据,buf
25     {
26         perror("write:");
27         exit(1);
28     }else
29     {
30         printf("Wirte %s size=%d\n",buf,size);
31     }
32     lseek(fd,0,SEEK_SET);//文件指针定位到文件头
33     if((size = read(fd,buf_r,10))<0)//读10个字节的数据,这里没有考虑字符串最后一个字节为‘\0‘,要完善
34     {    
35         perror("read:");
36         exit(1);
37     }else
38     {
39         printf("read from file:%s size=%d\n",buf_r,size);
40            } 
41         if( close(fd) < 0)//别忘记关闭
42     {
43         perror("Close:");
44         exit(1);
45     }else
46     {
47         printf("Close hello2.txt\n");
48     }
49     exit(0);
50 }

文件的访问涉及到进程间同步、互斥问题,采用Linux的fcntl()函数来加锁。

 1 //function lock_set 
 2 void lock_set(int fd,int type)
 3 {
 4     struct flock lock;
 5     lock.l_whence = SEEK_SET;
 6     lock.l_start = 0;
 7     lock.l_len = 0;
 8     while(1)
 9     {
10         lock.l_type = type;
11         if(fcntl(fd, F_SETLK,&lock) == 0) //如果要操作的文件已经加"写入锁"则fcntl() 返回非0值
12         {
13             if(lock.l_type == F_RDLCK)
14                 printf("read lock set by %d\n",getpid());
15             else if (lock.l_type == F_WRLCK)
16                 printf("write lock set by %d\n",getpid());
17             else if (lock.l_type == F_UNLCK)
18                 printf("release lock by %d\n",getpid());
19             return ;
20         }
21         fcntl(fd, F_GETLK,&lock);//上锁失败说明文件被锁住,则用"F_GETLK"来获取该锁的类型,包括上锁线程ID
22         if(lock.l_type != F_UNLCK)
23         {
24             if(lock.l_type == F_RDLCK)
25                 printf("read lock already set by %d\n",
26                     lock.l_pid);
27             else if(lock.l_type == F_WRLCK)
28                 printf("write lock already set by %d\n",
29                     lock.l_pid);
30              getchar();
31         }
32     }
33 }

下面演示A进程给文件上"写入锁",然后B进程给文件上"读锁"的实验现象:
Souce Code  of A :

 1 //hello3.c 即A 进程
 2 #include <unistd.h>
 3 #include <sys/file.h>
 4 #include <sys/types.h>
 5 #include <stdio.h>
 6 #include <stdlib.h>
 7 #include <fcntl.h>
 8 //function lock_set 
 9 //...
10 int main(void)
11 {
12     int fd;
13     fd=open("/tmp/hello3.txt",O_RDWR | O_CREAT,0666);
14     if(fd < 0)
15     {
16         perror("open");
17         exit(1);
18     }
19     //lock "write"
20     lock_set(fd, F_WRLCK);//给"hello3.txt"文件上"写入锁"
21     getchar();//等待,(按回车继续执行程序)
22     //then unlock
23     lock_set(fd,F_UNLCK);//去锁
24     getchar(); 
25     close(fd);
26     exit(0);
27 }

Souce Code  of B:

 1 //hello4.c   即B进程
 2 #include <unistd.h>
 3 #include <sys/file.h>
 4 #include <sys/types.h>
 5 #include <stdio.h>
 6 #include <stdlib.h>
 7 #include <fcntl.h>
 8 //function lock_set 
 9 //...
10 int main(void)
11 {
12     int fd;
13     fd=open("/tmp/hello3.txt",O_RDWR | O_CREAT,0666);
14     if(fd < 0)
15     {
16         perror("open");
17         exit(1);
18     }
19     //lock "read"
20     lock_set(fd,F_RDLCK);//给我文件hello3.txt上"读锁"
21     getchar();
22     //then unlock
23     lock_set(fd,F_UNLCK);
24     getchar(); 
25     close(fd);
26     exit(0);
27 }

 

运行效果,

 Step1:运行A进程(./hello3):

技术分享

Step2:打开另一终端,运行B进程(./hello4):

技术分享

Step3:A进程对应终端中按下回车键:

技术分享

Step4:B进程终端中按下回车键:

技术分享

OK,读写锁实验结束。

下面再了解下IO多路复用(用select),这个对我来说有点难理解,贴上代码和效果图,以后斟酌。

 1 //select.c
 2 #include <fcntl.h>
 3 #include <stdio.h>
 4 #include <unistd.h>
 5 #include <stdlib.h>
 6 #include <time.h>
 7 int main(void)
 8 {
 9     int fds[2];
10     char buf[7];
11     int i,rc,maxfd;
12     fd_set inset1,inset2;
13     struct timeval tv;
14     if((fds[0] = open("/tmp/hello5.txt",O_RDWR | O_CREAT,0666))<0)
15         perror("open hello5");
16     if((fds[1] = open("/tmp/hello50.txt",O_RDWR | O_CREAT,0666))<0)
17         perror("open hello50");
18     if((rc = write(fds[0],"hello!\n",7)))
19         printf("rc=%d\n",rc);
20     lseek(fds[0],0,SEEK_SET);
21     maxfd = fds[0]>fds[1] ? fds[0] : fds[1];
22     FD_ZERO(&inset1);
23     FD_SET(fds[0],&inset1);
24     FD_ZERO(&inset2);
25     FD_SET(fds[1],&inset2);
26     tv.tv_sec=2;
27     tv.tv_usec=0;
28     while(FD_ISSET(fds[0],&inset1) || FD_ISSET(fds[1],&inset2))
29     {
30         if(select(maxfd+1,&inset1,&inset2,NULL,&tv)<0)
31             perror("select");
32         else
33          {
34             if(FD_ISSET(fds[0],&inset1))
35             {
36                 rc = read(fds[0],buf,7);
37                 if(rc>0)
38                 {
39                  buf[rc]=\0;
40                  printf("read %s\n",buf);
41                 }else
42                  perror("read");
43             }
44             if(FD_ISSET(fds[1],&inset2))
45             {
46                 rc = write(fds[1],buf,7);
47                 if(rc>0)
48                 {
49                  buf[rc]=\0;
50                  printf("rc=%d,write:%s\n",rc,buf);
51                 }else
52                     perror("write");
53                 sleep(10);
54             }
55          }
56     }
57     exit(0);
58 }

效果图:

技术分享

感谢您的阅读,boyang987 。转载请注明出处。

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。