Unix进程通信:管道

匿名管道

原理
  • 内核空间的队列式内存(缓冲区)
  • 队列式内存,内核管理同步和互斥,而共享内存和文件通信需要信号量或者锁机制来保证同步互斥
特点
  • 半双工
  • 进程全部退出后,匿名管道自动释放,所以数据无法保存
  • 可以使用read write close,不能用lseek(队列读写)
  • 常用与父子进程间通信(匿名管道来进行非亲缘进程间通信需要辅助以文件描述符?)
  • 由内核管理的队列读写方式,自带同步互斥功能

API

#include <unistd.h>
int pipe(int pipefd[2]);

参数表:
pipefd[2]:读端和写端的文件描述符
返回值:
0:成功
-1:出错

示例

/*
匿名管道用于fork的父子进程之间
整形数组两个成员分别是读端和写端,对应两个文件描述符
虽然进程可以同时获得读端和写端两个文件描述符,但是,
由于匿名管道应该是半双工的,所以真正使用的时候,
发送方应该先关闭读端描述符,接收方应该关闭写端描述符
如果想全双工通信,应该建立两个匿名管道,如果用一个会发生错乱

pfd[0]对应读,pfd[1]对应写
1. int pfd[2]
2. pipe(pfd)
3. 父write(pfd[1],"123456",7)
   子read(pdf[0],buf,7)  
*/

//匿名管道用于父子进程间的通信。
//父写子读
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
using namespace std;

int main()
{

    char buf[100];
    
    int pfd[2];
    
    if( ( pipe(pfd) ) == -1)
    {
        perror("pipe");
        exit(1);
    }
    
    
    int pid;
    if( ( pid=fork() ) == -1)
    {
        perror("fork");
        exit(1);    
    }
    else if(pid == 0)//子进程,读
    {
        close(pfd[1]);
        sleep(1);
        read(pfd[0],buf,7);
        cout << buf << endl;
        close(pfd[0]);
    }
    else
    {
        close(pfd[0]);
        write(pfd[1],"123456",7);//父进程,写
        close(pfd[1]);
        wait(NULL);
        
    }

    return 0;
}

命名管道

原理
  • 内核空间的队列式内存
  • 又名(FIFO文件)
特点
  • 文件系统可见,有对应的文件节点信息
  • 虽然文件系统里有,但是硬盘中没有
  • 因为有名称,非亲缘进程可以依靠他通信
  • 按照文件操作进行操作(lseek除外)
API
#include <sys/stat.h>
int mkfifo(char *filename,mode_t mode);

参数表:
filename:命名管道名称
mode:使用方式(如0644)
返回值:
0:成功
-1:失败

示例代码

写端

  1 #include <sys/stat.h>//mkfifo() 
  2 #include <sys/types.h>
  3 #include <fcntl.h>
  4 #include <unistd.h>//sleep(),write(),close()
  5 
  6 int main()
  7 {
  8         char buf[100];
  9         int fd;
 10 
 11 
 12 
 13         mkfifo("testpipe",0644);
 14         fd = open("testpipe",O_WRONLY);
 15         write(fd,"123456",7);
 16         close(fd);
 17 
 18         sleep(10);
 19         return 0;
 20 }    

读端

  1 #include <sys/stat.h>
  2 #include <sys/types.h>
  3 #include <fcntl.h>
  4 #include <unistd.h>
  5 
  6 #include <iostream>
  7 using namespace std;
  8 
  9 int main()
 10 {
 11         char buf[100];
 12         int fd;
 13         sleep(1);
 14         fd = open("testpipe",O_RDONLY);
 15         read(fd,buf,7);
 16         cout << buf <<endl;
 17         
 18         close(fd);
 19         return 0;
 20 }                                                                                           
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容