Linux进程间通信——命名管道

目录

  • mkfifo
  • 命名管道
    • 命名管道与匿名管道的区别
    • 命名管道实现进程间通信示例
      • client.c
      • server.c
      • 如何让Makefile编译多个文件

mkfifo

Linux进程间通信——命名管道_第1张图片
现在先通过这段命令来创建一个FIFO文件

mkfifo fifo

接着我们会发现目录下出现了这个文件

在这里插入图片描述
开始的"p"代表"fifo"是一个管道文件,接下来我们创建两个进程,一个向fifo写数据,另一个从fifo读数据
在这里插入图片描述

命名管道

进程间的通信根本就是要让不同的进程看到同一份资源,而匿名管道利用的是子进程继承父进程资源的特性,让他们看到同一份资源。那么在没有血缘关系的进程间这种方式就行不通了。那么在这样的情况下我们可以使用命名管道进行进程间通信

命名管道与匿名管道的区别

1.匿名管道由pipe函数创建并打开
2.命名管道由mkfifo函数创建,打开用open
3.FIFO与pipe之间唯一的区别在于它们创建和打开的方式不同,一旦这些工作完成之后,它们具有相同的语义

命名管道实现进程间通信示例

在同一个目录下我们分别创建server.c和client.c(同时编译两个文件的操作见"如何让Makefile编译多个文件")文件,分别代表服务端和客户端,我们希望客户端向fifo写入数据,客户端接收数据并做出反馈

client.c

int main()
  4 {
  5   int fd = open(MY_FIFO, O_WRONLY);
  6   if (fd < 0)
  7   {
  8     perror("open");
  9     return 1;
 10   }
 11   while (1)
 12   {
 13     char buffer[64] = { 0 };
 14     printf("input: ");
 15     fflush(stdout);
 16     ssize_t s = read(0, buffer, sizeof(buffer) - 1); // 0文件是标准输入
 17     if (s > 0)
 18     {
 19       buffer[s - 1] = 0;
 20     //  printf("%s\n", buffer);
 21       write(fd, buffer, strlen(buffer));
 22     }
 23 
 24   }
 25   return 0;
 26 }

server.c

2 int main()                                  
  3 {                                  
  4   umask(0);                                  
  5   if (mkfifo(MY_FIFO,0666 ) < 0)
  6   {                                  
  7     perror("mkfifo");                
  8     return 1;                                          
  9   }                                            
 10   int fd = open(MY_FIFO, O_RDONLY);  
 11   if (fd < 0)       
 12   {                                     
 13     perror("open");                            
 14     return 2;                        
 15   }                                                  
 16                                                
 17   while (1)                          
 18   {                               
 19     char buffer[64] = { 0 };                 
 20     ssize_t s = read(fd, buffer, sizeof(buffer) - 1);
 21     if (s > 0)                                                
 22     {
 23       buffer[s] = 0;                                      
 24       if (strcmp(buffer, "show") == 0)          
 25       {                                
 26         if (fork() == 0)                              
 27         {
 28          execl("/usr/bin/ls", "ls", "-l", NULL);
 29         }                                
 30         waitpid(-1, NULL, 0);                             
 31       }      
 else if (strcmp(buffer, "train") == 0)
 35       {
            // 当输入train时,运行sl,该进程下载方式为yum install sl命令
 36         execl("/usr/bin/sl", "sl", NULL);
 37       }
 38       else 
 39       {
 40          printf("client: %s\n", buffer); 
 41       }
 42     }
 43     else if (s == 0)
 44     {
 45       printf("client quit\n");
 46       break;
 47     }
 48     else 
 49     {
 50       perror("read");
 51       break;
 52     }
 53   }
 54 
 55   close(fd);
 56   return 0;
 57 }   

如何让Makefile编译多个文件

我们可以先写一个伪文件all,并指明all需要依靠client和server文件,之后在写client和server需要的操作,具体Makefile如下

.PHONY:all
all:client server
client:client.c
	gcc -o $@ $^
server:server.c
	gcc -o $@ $^
.PHONY:clean
clean:
	rm -f client server fifo

你可能感兴趣的:(Linux,操作系统,linux,服务器,运维)