`
xidajiancun
  • 浏览: 449437 次
文章分类
社区版块
存档分类
最新评论

Java使用管道实现进程间通讯

 
阅读更多

转载请注明出处:http://blog.csdn.net/jmppok/article/details/17500739

1.进程通讯

大家都知道进程间通讯有三种常用方式:

1)管道

2)共享内存

3)socket

baidu也有说8种方式的,其实基本都是这三种方式的进一步细化。


2.Java进程通讯

Java没有共享内存机制,同时Java的管道也只能用于Java线程间的通讯。

下面是一个关于Java的管道简单的介绍:

Java提供管道功能,实现管道通信的类有两组:PipedInputStream和PipedOutputStream或者是PipedReader和PipedWriter。管道通信主要用于不同线程间的通信。

一个PipedInputStream实例对象必须和一个PipedOutputStream实例对象进行连接而产生一个通信管道。PipedOutputStream向管道中写入数据,PipedIntputStream读取PipedOutputStream向管道中写入的数据。一个线程的PipedInputStream对象能够从另外一个线程的PipedOutputStream对象中读取数据。

看来Java只能通过Socket实现进程间通讯了。Socket本身确实具有很好的通用性,而且可以跨主机通讯。但是Scoket本身也有一些弱点,如效率相对其他方式较低,开发成本较高等。最重要的是,这篇文章我们要介绍的是Java如何使用PIPE实现进程间通讯。所以只好委屈一下Socket了。

3.Java通过管道实现进程通讯

3.1管道的本质

首先,我们需要说明一个基本概念:什么是管道?

管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于具有亲缘关系的进程之间,这是它与有名管道的最大区别。有名管道叫named pipe或者FIFO(先进先出),可以用函数mkfifo()创建。


Linux管道的实现机制

从本质上说,管道也是一种文件,但它又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题,具体表现为:·
1)限制管道的大小。实际上,管道是一个固定大小的缓冲区。在Linux中,该缓冲区的大小为1页,即4K字节,使得它的大小不象文件那样不加检验地增长。使用单个固定缓冲区也会带来问题,比如在写管道时可能变满,当这种情况发生时,随后对管道的write()调用将默认地被阻塞,等待某些数据被读取,以便腾出足够的空间供write()调用写。
2)读取进程也可能工作得比写进程快。当所有当前进程数据已被读取时,管道变空。当这种情况发生时,一个随后的read()调用将默认地被阻塞,等待某些数据被写入,这解决了read()调用返回文件结束的问题
注意:
从管道读数据是一次性操作,数据一旦被读,它就从管道中被抛 弃,释放空间以便写更多的数据。

管道的结构
在Linux 中,管道的实现并没有使用专门的数据结构,而是借助了文件系统的file结构和VFS的索引节点inode。

过将两个file 结构指向同一个临时的VFS 索引节点,而这个VFS引节点又指向一个物理页面而实现的。

3.2 Java如何使用管道通讯

上面说到,管道实际上就是一个file结构和一个VFS的索引。也就是说管道是一个虚拟的文件。那在Java中是不是就可以通过直接读写这个文件,从而实现PIPE通讯的效果呢?

答案当然是肯定的。其步骤如下:

1)首先要创建一个管道文件,这一点Java 做不到,我们要借助C/C++中的mkfifo()函数来实现。

以下代码创建并打开两个管道,一个用于读取输入,一个用于输出:

	char name1[1024];
	char name2[1024];
	sprintf(name1,"./process_in");
	sprintf(name2,"./process_out");
	if(mkfifo(name1,0666 )<0)
	{
	 printf("\n error when mkfifo");	
	}
	if(mkfifo(name2,0666 )<0)
	{
	 printf("\n error when mkfifo");	
	}


	int fd1, fd2;
	if ((fd1 = open (name1, O_RDWR ))<0)
    	{
         perror("Could not open named pipe.");
    	}
	if ((fd2 = open (name2, O_RDWR ))<0)
    	{
         perror("Could not open named pipe.");
    	}

这是查看当前目录,可以看到两个Pipe文件,它和普通文件不同,具有p属性,表明是一个管道文件。

2)Java中,使用文件读写的方式打开这两个文件,即可进行读写。

			String namedPipe1=workdir+"/process_in";
			String namedPipe2=workdir+"/process_out";

			File pipe1 = new File(namedPipe1);
			File pipe2 = new File(namedPipe2);
			
			BufferedReader reader = new BufferedReader(new FileReader(pipe2));
			//DataInputStream reader = new DataInputStream(new FileInputStream(pipe2));
			BufferedWriter writer = new BufferedWriter(new FileWriter(pipe1));

			writer.write("test");

            char [] buf = new char[8];
			reader.read(buf);



3)需要注意的问题

1)Java最好用单独的线程来读数据;

2)Java写完数据后,需要flush();


分享到:
评论

相关推荐

    java进程间管道通信1

    其步骤如下:1)首先要创建一个管道文件,这一点Java 做不到,我们要借助C/C++中的mkfifo()函数来实现。} 这是查看当前目录,可以看到两个Pipe

    java进程间通讯机制代码----RMI、共享内存、Socket、管道

    java进程间通讯机制代码----RMI、共享内存、Socket、管道,等方式,每种方法我都讲了原理和例子程序,很有参考意义。在网上很难找到的。

    java 进程间利用管道通信实例

    简单的进程管道通信,非常好用,容易上手和修改,是eclipse工程文件

    进程间通信之消息队列 ( message queue )——完整代码

    进程间通信之消息队列 ( message queue ) 消息队列是消息的链表,具有特定的格式,并由消息队列标识符标识. 七种进程间通信方式: 一.无名管道( pipe ) 二.有名管道( fifo ) 三.共享内存 ( shared memory ) 四....

    java进程通讯

    java进程间通讯机制代码 RMI(Remote Method Invocation)是一种基于Java的分布式编程模型,为java程序提供远程访问服务接口。

    java进程间通讯笔记

    我整理的java进程间通讯的笔记,包括原理讲解和代码,例子程序。socket、共享内存、RMI、管道。

    java进程间tx1

    (2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信 (3)信号(Signa

    编程模拟多进程共享临界资源

    要求产生3个进程: 1、两个进程模拟需要进入临界区的用户进程,当需要进入临界区时,显示:“进程x请求进入临界区…”,同时向管理进程提出申请;...4、进程间通信可以采用信号、消息传递、管道或网络通信方式。

    Java编程线程间通信与信号量代码示例

    主要介绍了Java编程线程间通信与信号量代码示例,具有一定借鉴价值,需要的朋友可以参考下。

    多进程共享临界资源

    要求产生至少3个进程: 1、两个进程模拟需要进入临界区的用户进程,当需要进入临界区时,显示:“进程x请求进入临界区…”,同时向管理进程提出申请;...4、进程间通信可以采用信号、消息传递、管道或网络通信方式。

    高级UNIX编程 pdf 电子书

    全书共9章,内容包括:基本概念、基本文件I/O、高级文件I/0、终端I/O、进程与线程、基本进程间通信、高级进程间通信、网络技术与套接字,以及信号与定时器等。涉及POSIX、FreeBSD、Solaris、Linux等几大主流系统...

    JAVA程序设计教程

    Java程序.............................................................................................6 1.3.1 Java程序的结构 ...........................................................................

    python多线程DAY03.txt

    4.进程间通信 管道 消息队列 共享内存 信号 信号量 套接字 管道: Pipe() fd.recv() fd.send() 消息队列: Queue() q.get() q.put() q.full() q.empty() q.qsize() q.close() 共享内存: Value() Array() ...

    php中stream(流)的用法

    在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备、外部文件等。根据流的方向又可以分为输入流和输出流,同时可以在其外围再套上其它流,比如缓冲流,这样就可以得到更多流处理方法...

    C语言解析教程(原书第4版)(美) 凯利.pdf

    12.3 使用pipe()实现进程间的通信 12.4 信号 12.5 例子:哲学家用餐问题 12.6 矩阵的动态分配 12.6.1 为什么二维数组无法满足要求 12.6.2 用指针数组创建矩阵 12.6.3 调整下标范围 12.6.4 一次分配所有内存 12.7 ...

    In-The-Queue-Please:在排队论中实现确定性和随机模型,包括图形结果(如果存在模型)

    排队论在软件开发中用于诸如项目管理看板,进程间通信消息队列和开发连续部署管道之类的目的。构造一个排队模型,以便可以预测队列长度和等待时间。排队理论符号:排队论使用带有希腊字母的符号。我们使用一些流行的...

Global site tag (gtag.js) - Google Analytics