zoukankan      html  css  js  c++  java
  • 进程间通信——管道

    1、进程间通信

        每个进程有独立的用户地址空间,所以一个进程是看不到另一个进程中的数据包括全局变量。进程间通信是需要通过内核来进行的,内核中开辟一块缓存,不同的进程将数据写到这里或从这里读取,从而实现不同进程之间的通信,内核提供的这种机制称为进程间通信。进程间通信方式有多种,不同的方式提供的共享资源形式不同或者提供者不同。管道就是这其中的一种。

    2、管道的创建

        管道的创建使用pipe()系统调用,关于此系统调用可参见另一篇文章中的描述——高级IO函数

    3、管道实现进程间通信

        管道一般用于有关系的进程之间的通信,例如父子进程之间的通信:

    • 父进程创建了一个管道,f[0]、f[1]分别为管道两端的文件描述符
    • 父进程通过fork函数创建子进程,此时子进程继承了父进程的管道,也有一对文件描述符f[0]、f[1]。
    • 由于管道只能单向传输数据,所以父子进程必须一个关闭f[0],另一个关闭f[1],才能实现通信。如下图所示,即为管道实现进程间通信的抽象描述。



        管道实现进程间通信代码示例:

    #include<stdio.h>
    #include<unistd.h>
    #include<sys/types.h>
    #include<sys/wait.h>
    int main()
    {
    	int fd[2];
    	int ret = pipe(fd);
    	if(ret == -1)
    	{
    		printf("pipe error
    ");
    		return 1;
    	}
    
    	pid_t id = fork();
    	if(id == 0)   //子进程
    	{
    		close(fd[1]);
    		char buf[100];
    		while(1)
    		{
    			memset(buf, '', sizeof(buf));
    			size_t s = read(fd[0], buf, sizeof(buf));
    			if(s > 0)
    			{
    				buf[s - 1] = '';
    				printf("%s", buf);
    			}
    			else
    				break;
    		}
    		close(fd[0]);
    		return 0;
    	}
    	else if(id > 0)  //父进程
    	{
    		close(fd[0]);
    		char* wrbuf = "hello world";
    		int i = 5;
    		while(i--)
    		{
    			ret = write(fd[1], wrbuf, strlen(wrbuf));
    			if(ret < 0)
    			{
    				printf("write error
    ");
    				break;
    			}
    			sleep(2);
    		}
    		close(fd[1]);
    		int stat_loc;
    		wait(&stat_loc);
    		return 0;
    	}
    	else
    	{
    		printf("fork error
    ");
    		return 1;
    	}
    }

    4、管道的读写状态

    • 当管道容量满时,且读端文件描述符引用计数大于0,则再次调用write会阻塞;
    • 当读端文件描述符引用计数等于0,写端再次调用write时,进程会收到SIGPIPE信号,导致进程终止;
    • 当管道数据为空时,且写端文件描述符引用计数大于0,则再次调用read会阻塞,直到有数据可读;
    • 当写端文件描述符引用计数等于0,读端再次调用read时,返回0,如同读到文件末尾(EOF)。

    5、管道容量

        管道有一个容量限制,规定了如果应用程序没有将数据从管道中读走的话,该管道最多能被写入的数据字节数。当前的Linux,管道容量默认为65536字节,也可以使用fcntl函数修改管道容量。

        测试管道容量,可以采用对管道只写不读,当write阻塞时说明管道已满,计算write进去的数据字节数,即为管道容量。

  • 相关阅读:
    判断qq浏览器和uc浏览器?
    做前端能避免的错误总结
    css布局
    border-radius后面写px/rem与百分比有什么区别?
    vertical-align
    localstorage和cookie的设置方法和获取方法
    怎么让列表的文字只显示两行,多出的出现省略号?
    avalon在公共页面里面写的功能,怎么让某些页面不引用到这个方法和html?
    小程序
    webpack
  • 原文地址:https://www.cnblogs.com/fangyan5218/p/10618253.html
Copyright © 2011-2022 走看看