嵌入式开发记录-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会阻塞

浙公网安备 33010602011771号