嵌入式开发记录-day14 进程间通信-无名管道和有名管道

1、进程间通信:无名管道

  pipe, pipe2 - create pipe

  int pipe(int pipefd[2])

  实验目的:使用fork() 创建一个子进程,子进程、父进程之间通过管道通信;子进程读取管道数据,并打印出来;父进程将键盘输入数据写入管道中;

 1 #include <unistd.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 
 5 void ReadData(int*);
 6 void WriteData(int*);
 7 
 8 int main(int argc,char* argv[])
 9 {
10     int pipes[2],rc;
11     pid_t pid;
12     
13     rc = pipe(pipes); // 创建一个pipes管道
14     if(rc == -1){
15         perror("pipes \n");
16         exit(1);
17     }
18     pid = fork();
19     switch(pid)
20     {
21         case -1:
22             perror("\n perror\n");
23             exit(1);
24         case 0: // 子进程读管道数据
25             //printf("enter child process\n");
26             ReadData(pipes);
27         default:  // 父进程写管道数据
28             //printf("enter parent process\n");
29             WriteData(pipes);
30     }
31     
32     return 0;
33 }
34 
35 void ReadData(int pipes[])
36 {
37     int c,rc;
38     close(pipes[1]); // 关闭写管道
39     while((rc = read(pipes[0],&c,1)) > 0){  // pipes[0]用于读管道
40         putchar(c);
41     }
42     exit(0);
43 }
44 void WriteData(int pipes[])
45 {
46     int c,rc;
47     close(pipes[0]); // 关闭读管道    
48     
49     while((c = getchar()) > 0){
50         rc = write(pipes[1],&c,1); // pipes[1] 用于写管道
51         if(rc == -1){
52             perror("parent write\n");
53             close(pipes[1]);
54             exit(1);
55         }
56     }
57     close(pipes[1]);
58     exit(0);
59 }

2、进程间通信:有名管道,

  由于实验需求创建一个数据文件data.txt

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 void filecopy(FILE* f,char* buf);
 5 int main()
 6 {
 7     FILE* f;
 8     int i = 10000;
 9     char buf[] = "I want to learn linux\n";
10     char* file1 = "data.txt";
11     
12     printf("begining...\n");
13     f = fopen(file1,"a+");
14     if(f == NULL){
15         printf("can't open file %s\n",file1);
16     }
17     while(i--){
18         filecopy(f,buf);
19     }
20     fclose(f);
21     
22     printf("over....\n");
23     return 0;
24 }
25 void filecopy(FILE* f,char* buf)
26 {
27     int i,j = 0;
28     i = strlen(buf)-1;
29     while(i--){
30         putc(buf[j],f);
31         j++;
32     }
33     putc('\n',f);
34 }

3、向管道写数据 writepipe.c

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <sys/types.h>
 4 #include <sys/stat.h>
 5 #include <unistd.h>
 6 #include <stdlib.h>
 7 #include <fcntl.h>
 8 #include <limits.h>  // PIPE_BUF
 9 
10 int main()
11 {
12     const char* fifo_name = "my_fifo";  
13     // 定义管道名称 定义的路径必须有权限读写 U盘没有访问权限,会出错
14     char* file1 = "data.txt";   // 从data.txt数据文件中读数据
15     int res = 0;
16     int pipe_fd  = -1;  // 定义一个管道文件句柄
17     const int open_mode = O_WRONLY;   // 写操作打开文件
18     int data_fd = -1;  // 定义数据文件句柄
19     char buf[PIPE_BUF+1];  // PIPE_BUF 在man 7 pipe中欧定义
20 
21     res = mkfifo(fifo_name,0777); 
22     printf("func mkfifo res:%d\n",res);
23     // 判断管道文件是否存在
24     if(access(fifo_name,F_OK) != 0){
25         res = mkfifo(fifo_name,0777);   // 管道文件不存在 则创建管道
26         if(res != 0){  // 创建失败
27             fprintf(stderr,"Could not create fifo:%s\n",fifo_name);
28             exit(EXIT_FAILURE);
29         }
30     }
31     printf("Process %s open FIFO O_WRONLY\n");
32     pipe_fd = open(fifo_name,open_mode); // 以写方式打开管道文件
33     data_fd = open(file1,O_RDONLY);      // 以读方式打开数据文件
34     printf("Process %d result %d\n",getpid(),pipe_fd);
35     
36     if(pipe_fd != -1){   // 打开管道文件成功
37         int bytes_read = 0;
38         bytes_read = read(data_fd, buf,PIPE_BUF);  // 第一次从数据文件中读取数据
39         buf[bytes_read] = '\0';
40         while(bytes_read > 0){
41             res = write(pipe_fd,buf,bytes_read);  // 读取到的数据 写入管道
42             if(res ==  -1) {
43                 fprintf(stderr,"write error on pipes\n");
44                 exit(EXIT_FAILURE);
45             }
46         //    bytes_send += res;
47             bytes_read = read(data_fd,buf,PIPE_BUF); // 读取数据文件
48             buf[bytes_read] = '\0';
49         }
50         close(pipe_fd);   // 关闭打开的管道文件流
51         close(data_fd);   // 关闭打开的数据文件流
52     }else{   // 打开管道文件失败
53         printf("open pipe failed\n");
54         exit(EXIT_FAILURE);
55     }
56     printf("Process %d finished\n",getpid());
57     exit(EXIT_SUCCESS);
58     
59     return 0;
60 }
 1 /***********************
 2 读写有名管道:
 3     
 4 #include <sys/types.h>
 5 #include <sys/stat.h>
 6 int mkfifo(const char *pathname, mode_t mode);
 7 
 8 检验文件权限:access()
 9 #include <unistd.h>
10 int access(const char *pathname, int mode);
11 
12 需要后台运行 ./mnt/disk/writepipes &
13 使用命令查看后台运行程序:jobs
14 time ./mnt/disk/readpipe   查看运行时间
15 
16 向管道里写创建好的数据
17 需要注意:给管道写数据 需要使用权限O_WRONLY
18 */

4、读管道操作 readpipe.c

 1 /************************************
 2 读有名管道:
 3 从管道中读读取到的数据
 4 注意:读管道数据:需要以O_RDONLY方式打开管道文件,
 5 否则open会阻塞
 6 */
 7 #include <stdio.h>
 8 #include <string.h>
 9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <fcntl.h>
14 #include <limits.h>  // PIPE_BUF
15 int main()
16 {
17     const char* fifo_name = "my_fifo";
18     int bytes_read = 0;
19     int bytes_write = 0;
20     int pipe_fd = -1;
21     int data_fd = -1;
22     const int open_mode = O_RDONLY;
23     char buf[PIPE_BUF+1];
24     int res = 0;
25     
26     memset(buf,'\0',sizeof(buf));
27     printf("Process %d open FIFO O_RDONLY\n",getpid());
28     pipe_fd = open(fifo_name,open_mode);  // 打开管道文件
29     // 写另一个文件句柄中  文件在指定的路径中
30     data_fd = open("DataFormFIFO.txt",O_WRONLY|O_CREAT,0644);  // 打开或者创建一个数据文件
31     printf("Process %d result %d\n",getpid(),pipe_fd);
32     
33     if(pipe_fd != -1){  // 打开管道文件成功
34         do{
35             res = read(pipe_fd, buf,PIPE_BUF);// 读取管道文件数据到buf中
36             bytes_write = write(data_fd,buf,res); // 将buf中的数据写到数据文件中
37             bytes_read += res;
38         }while(res >0);
39         close(pipe_fd);  
40         close(data_fd);
41     }else
42         exit(EXIT_FAILURE);
43     
44     printf("Process %d finished,%d bytes read\n",getpid(),bytes_read);
45     exit(EXIT_SUCCESS);
46     
47 }

一定注意读写管道的打开的方式,否则open会阻塞

 

  

 

posted @ 2020-06-21 22:51  笑不出花的旦旦  阅读(157)  评论(0)    收藏  举报