进程间通信的方法
2016-07-07 22:11
399 查看
进程间通信的方法主要有以下几种:
(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
(2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关 系 进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。
(3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送 信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。
(4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺
(5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
(6)内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
(7)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
(8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。
而在java中我们实现多线程间通信则主要采用”共享变量”和”管道流”这两种方法
方法一 通过访问共享变量的方式(注:需要处理同步问题)
方法二 通过管道流
其中方法一有两种实现方法,即
方法一 a)通过内部类实现线程的共享变量
代码如下:
b)通过实现Runnable接口实现线程的共享变量
代码如下:
方法二(通过管道流):
代码如下:
(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
(2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关 系 进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。
(3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送 信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。
(4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺
(5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
(6)内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
(7)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
(8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。
而在java中我们实现多线程间通信则主要采用”共享变量”和”管道流”这两种方法
方法一 通过访问共享变量的方式(注:需要处理同步问题)
方法二 通过管道流
其中方法一有两种实现方法,即
方法一 a)通过内部类实现线程的共享变量
代码如下:
public class Innersharethread { public static void main(String[] args) { Mythread mythread = new Mythread(); mythread.getThread().start(); mythread.getThread().start(); mythread.getThread().start(); mythread.getThread().start(); } } class Mythread { int index = 0; private class InnerThread extends Thread { public synchronized void run() { while (true) { System.out.println(Thread.currentThread().getName() + "is running and index is " + index++); } } } public Thread getThread() { return new InnerThread(); } } /** * 通过内部类实现线程的共享变量 * */ public class Innersharethread { public static void main(String[] args) { Mythread mythread = new Mythread(); mythread.getThread().start(); mythread.getThread().start(); mythread.getThread().start(); mythread.getThread().start(); } } class Mythread { int index = 0; private class InnerThread extends Thread { public synchronized void run() { while (true) { System.out.println(Thread.currentThread().getName() + "is running and index is " + index++); } } } public Thread getThread() { return new InnerThread(); } }
b)通过实现Runnable接口实现线程的共享变量
代码如下:
public class Interfacaesharethread { public static void main(String[] args) { Mythread mythread = new Mythread(); new Thread(mythread).start(); new Thread(mythread).start(); new Thread(mythread).start(); new Thread(mythread).start(); } } /* 实现Runnable接口 */ class Mythread implements Runnable { int index = 0; public synchronized void run() { while (true) System.out.println(Thread.currentThread().getName() + "is running and the index is " + index++); } } /** * 通过实现Runnable接口实现线程的共享变量 */ public class Interfacaesharethread { public static void main(String[] args) { Mythread mythread = new Mythread(); new Thread(mythread).start(); new Thread(mythread).start(); new Thread(mythread).start(); new Thread(mythread).start(); } } /* 实现Runnable接口 */ class Mythread implements Runnable { int index = 0; public synchronized void run() { while (true) System.out.println(Thread.currentThread().getName() + "is running and the index is " + index++); } }
方法二(通过管道流):
代码如下:
public class CommunicateWhitPiping { public static void main(String[] args) { /** * 创建管道输出流 */ PipedOutputStream pos = new PipedOutputStream(); /** * 创建管道输入流 */ PipedInputStream pis = new PipedInputStream(); try { /** * 将管道输入流与输出流连接 此过程也可通过重载的构造函数来实现 */ pos.connect(pis); } catch (IOException e) { e.printStackTrace(); } /** * 创建生产者线程 */ Producer p = new Producer(pos); /** * 创建消费者线程 */ Consumer c = new Consumer(pis); /** * 启动线程 */ p.start(); c.start(); } } /** * 生产者线程(与一个管道输入流相关联) * */ class Producer extends Thread { private PipedOutputStream pos; public Producer(PipedOutputStream pos) { this.pos = pos; } public void run() { int i = 8; try { pos.write(i); } catch (IOException e) { e.printStackTrace(); } } } /** * 消费者线程(与一个管道输入流相关联) * */ class Consumer extends Thread { private PipedInputStream pis; public Consumer(PipedInputStream pis) { this.pis = pis; } public void run() { try { System.out.println(pis.read()); } catch (IOException e) { e.printStackTrace(); } } }
相关文章推荐
- JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解
- 2016/07/07 apmserv5.2.6 Apache启动失败,请检查相关配置。MySQL5.1已启动。
- HBase学习之三: hbase filter(过滤器)和coprocessor(协处理器)统计行数的简单应用
- android笔记:BroadcastReceiver
- 初学hibernate
- 剑指offer-4-面试题22:栈的压入、弹出序列
- [置顶] 【Linux】 进程通信--消息队列
- centos安装rabbitmq消息队列
- 2016/07/07 wamp中apache2.4.9允许外部访问的配置 重点是版本 版本不同配置效果不同
- NHibernate系列文章十六:使用程序集管理NHibernate项目(附程序下载)
- extern 声明 vs2012
- maven lib 复制到工程中
- win7环境mysql安装
- 最长回文串
- linux 内核配置与编译
- leetcode: Binary Tree Preorder Traversal
- JavaMail authenticating 535 error
- 【BFS和DFS的性质】[NOI2013]树的计数
- 第九天:排列活动顺序和估算活动资源,网络进度网络图,4种活动逻辑解析表,3种网络图绘制方法、确定依赖关系,提前量滞后量
- Android Fragment 碎片 简单代码