精华内容
下载资源
问答
  • 1.管道(pipe):管道是一种半双工的通信方式,数据只能单向流动,而且只能具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。 2.有名管道(named pipe) : 有名管道也是半双工的通信方式,但是它允许...
    1.管道(pipe):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
    
    2.有名管道(named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
    3.信号量(semophore) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
    4.消息队列(message queue) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
    5.信号 (sinal) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
    6.共享内存(shared memory) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
    7.套接字(socket) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器之间的进程间通信。


    几种通信方法总结综上所述.进程之间的多种通信方法各自有各自的优点和缺点:如果用户传递的信息较少.或是需要通过信号来触发某些行为.前文提到的软中断信号机制不失为一种简捷有效的进程间通信方式.但若是进程间要求传递的信息量比较大或者进程间存在交换数据的要求,那就需要考虑别的通信方式了。无名管道简单方便.但局限于单向通信的工作方式.并且只能在创建它的进程及其子孙进程之间实现管道的共享:有名管道虽然可以提供给任意关系的进程使用.但是由于其长期存在于系统之中,使用不当容易出错.所以普通用户一般不建议使用。消息缓冲可以不再局限于父子进程.而允许任意进程通过共享消息队列来实现进程间通信.并由系统调用函数来实现消息发送和接收之间的同步.从而使得用户在使用消息缓冲进行通信时不再需要考虑同步问题.使用方便,但是消息队列中信息的复制需要额外消耗CPU的时间.不适宜于信息量大或操作频繁的场合。共享内存针对消息缓冲的缺点改而利用内存缓冲区直接交换信息,无须复制,快捷、信息量大是其优点。但是共享内存的通信方式是通过将共享的内存缓冲区直接附加到进程的虚拟地址空间中来实现的.因此,这些进程之间的读写操作的同步问题操作系统无法实现。必须由各进程利用其他同步工具解决。另外,由于内存实体存在于计算机系统中.所以只能由处于同一个计算机系统中的诸进程共享,不方便网络通信。不同的进程通信方式有不同的优点和缺点.因此.对于不同的应用问题,要根据问题本身的情况来选择进程间的通信方式。
    一般来说,进程间的通信根据通信内容可以划分为两种:即控制信息的传送与大批数据传送。有时也把进程间控制信息的交换称为低级通信,而把进程间大批量数据的交换称为高级通信。
    展开全文
  • 上期,转载了一篇自定义的通信协议的制定以及使用的一篇帖子,个人觉得相当不错。 但是就目前而已,谷歌的PB使用要更广泛一些,不管是哪个方面。 对于PB的话,也就是Google Protocol Buffer。假如您网上搜索,...

    上期,转载了一篇自定义的通信协议的制定以及使用的一篇帖子,个人觉得相当不错。

    但是就目前而已,谷歌的PB使用要更广泛一些,不管是哪个方面。

    对于PB的话,也就是Google Protocol Buffer。假如您在网上搜索,应该会得到类似这样的文字介绍:

    Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,目前已经正在使用的有超过 48,162 种报文格式定义和超过 12,183 个 .proto 文件。他们用于 RPC 系统和持续数据存储系统。

    protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。

    官方文档给出的是:

    a language-neutral, platform-neutral, extensible way of serializing structured data for use in communications protocols, data storage, and more.

    或许您和我一样,在第一次看完这些介绍后还是不明白 Protobuf 究竟是什么,那么我想一个简单的例子应该比较有助于理解它。

    安装 Google Protocol Buffer

    可以在http://download.csdn.net/download/canlets/6878023 下载protobuf2.5.0。

    安装步骤如下所示:

    tar zxvf protobuf-2.4.1.tar.gz
    cd protobuf-2.4.1
    ./configure
    make
    make check
    make install
    安装结束。

    验证:
    查看是否安装成功:protoc --version
    如果出现:libprotoc 2.4.1 则说明安装成功!

    如果出现错误:

    tar zxvf protobuf-2.5.0.tar.gz
    ./configure
    make
    make check
    make install
    安装结束。

    验证:
    查看是否安装成功:protoc --version
    如果出现:libprotoc 2.5.0 则说明安装成功!

    安装完成后在终端下执行

      vim ~/.profile (我加在了/etc/profile里)

      打开配置文件,在该文件中添加

      export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

      然后保存退出,接下来执行

      source ~/.profile

      是配置文件修改生效,最后执行

      protoc --version

      查看protobuf版本以测试是否安装成功

    打开vsprojects目录,里面有一个.sln文件,打开 vsprojects里面有一个readme.txt,告诉了如何安装

    Protobuf的优点

    Protobuf 有如 XML,不过它更小、更快、也更简单。你可以定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数据结构。你甚至可以在无需重新部署程序的情况下更新数据结构。只需使用 Protobuf 对数据结构进行一次描述,即可利用各种不同语言或从各种不同数据流中对你的结构化数据轻松读写。

    它有一个非常棒的特性,即“向后”兼容性好,人们不必破坏已部署的、依靠“老”数据格式的程序就可以对数据结构进行升级。这样您的程序就可以不必担心因为消息结构的改变而造成的大规模的代码重构或者迁移的问题。因为添加新的消息中的 field 并不会引起已经发布的程序的任何改变。

    Protobuf 语义更清晰,无需类似 XML 解析器的东西(因为 Protobuf 编译器会将 .proto 文件编译生成对应的数据访问类以对 Protobuf 数据进行序列化、反序列化操作)。

    使用 Protobuf 无需学习复杂的文档对象模型,Protobuf 的编程模式比较友好,简单易学,同时它拥有良好的文档和示例,对于喜欢简单事物的人们而言,Protobuf 比其他的技术更加有吸引力。


    Protobuf的缺点

    Protbuf 与 XML 相比也有不足之处。它功能简单,无法用来表示复杂的概念。

    由于文本并不适合用来描述数据结构,所以 Protobuf 也不适合用来对基于文本的标记文档(如 HTML)建模。另外,由于 XML 具有某种程度上的自解释性,它可以被人直接读取编辑,在这一点上 Protobuf 不行,它以二进制的方式存储,除非你有 .proto 定义,否则你没法直接读出 Protobuf 的任何内容

    官方文档描述如下:for instance, protocol buffers would not be a good way to model a text-based document with markup (e.g. HTML), since you cannot easily interleave structure with text



    Protobuf环境的搭建

    步骤:

    1, 安装maven

    http://blog.csdn.net/jiangguilong2000/article/details/9284437

    2, 下载probuf源码和编译器

    http://blog.csdn.net/jiangguilong2000/article/details/9284297

    3, 拷贝文件,执行相应mvn install命令。 (protobuf并不提供jar包,需要自己执行命令生成)

    Note:

    在这个地方遇到了一个问题,错误信息如下:

    Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.3:run (generate-sources) on project protobuf-java: An Ant BuildException has occured: Execute failed: java.io.IOException: Cannot run program "..\src\protoc": CreateProcess error=2, ????????? ->

    原因:犯了了一个很2的问题,拷贝protoc.exe文件的路径拷错了。请详细比较步骤2中的路径,一定拷对路径。

    4,通过protoc.exe编译addressbook.proto文件

    http://blog.sina.com.cn/s/blog_653ac36d0101h9kn.html

    核心概念

    1,.proto文件

    相当于确定数据协议,数据结构中存在哪些数据,数据类型是怎么样

    2,modifiers

    2-1 required 不可以增加或删除的字段,必须初始化

    2-2 optional 可选字段,可删除,可以不初始化

    2-3 repeated 可重复字段, 对应到java文件里,生成的是List

    3,Message

    在proto文件里,数据的协议时以Message的形式表现的。

    4, Build

    生成具体的java类时,例如Person.java,同时会存在build方法。文档的意思是对于转化后的数据,具有唯一性,build提供了便利的方法来初始化这些数据。



    最后总结一下。人们一直在强调,同 XML 相比, Protobuf 的主要优点在于性能高。它以高效的二进制方式存储,比 XML 小 3 到 10 倍,快 20 到 100 倍。

    对于这些 “小 3 到 10 倍”,“快 20 到 100 倍”的说法,严肃的程序员需要一个解释。因此在本文的最后,让我们稍微深入 Protobuf 的内部实现吧。

    有两项技术保证了采用 Protobuf 的程序能获得相对于 XML 极大的性能提高。

    第一点,我们可以考察 Protobuf 序列化后的信息内容。您可以看到 Protocol Buffer 信息的表示非常紧凑,这意味着消息的体积减少,自然需要更少的资源。比如网络上传输的字节数更少,需要的 IO 更少等,从而提高性能。

    Protobuf 序列化后所生成的二进制消息非常紧凑,这得益于 Protobuf 采用的非常巧妙的 Encoding 方法。

    第二点我们需要理解 Protobuf 封解包的大致过程,从而理解为什么会比 XML 快很多。

    首先我们来了解一下 XML 的封解包过程。XML 需要从文件中读取出字符串,再转换为 XML 文档对象结构模型。之后,再从 XML 文档对象结构模型中读取指定节点的字符串,最后再将这个字符串转换成指定类型的变量。这个过程非常复杂,其中将 XML 文件转换为文档对象结构模型的过程通常需要完成词法文法分析等大量消耗 CPU 的复杂计算。

    反观 Protobuf,它只需要简单地将一个二进制序列,按照指定的格式读取到 C++ 对应的结构类型中就可以了。从上一节的描述可以看到消息的 decoding 过程也可以通过几个位移操作组成的表达式计算即可完成。速度非常快。

    所以综上所述,之前那篇的自定义的通信协议方法与PB有着非常相似的地方,但又不太相同。但是相对于xml而言,自定义的要优化了很多,但是比起PB却又有所不足,算是介于两者之间吧。但是由于PB最初是谷歌的内部方法,并且需要建立环境,相对比较麻烦,自定义的方法在这方面表现的就相当的简单,虽然xml也是如此,但是由于效率的缺乏,这点就显得非常的无力,虽然我们对xml的了解已经非常的深了。

    所以相比较之下。我个人认为,PB稍微优于自定义,明显优于xml,甚至可以淘汰xml了吧。




    展开全文
  • 进程的通信方式及其优缺点

    千次阅读 2017-09-17 17:41:35
    进程通信的含义 ...由于不同的进程运行各自不同的内存空间中,其中一个进程对于变量的修改另一方是无法感知的,因此,进程之间的消息传递不能通过变量或其他数据结构直接进行,只能通过进程间通信来完成

    进程通信的含义

    进程是转入内存并准备执行的程序,每个程序都有私有的虚拟地址空间,由代码,数据以及它可利用的系统资源(如文件,管道)组成.多进程/多线程是windows操作系统的一个基本特征.Linux系统一般都统称为进程.

    由于不同的进程运行在各自不同的内存空间中,其中一个进程对于变量的修改另一方是无法感知的,因此,进程之间的消息传递不能通过变量或其他数据结构直接进行,只能通过进程间通信来完成.进程间通信是指不同进程间进行数据共享和数据交换.

    进程通信的分类

    根据进程通信时信息量大小的不同,可以将进程通信划分为两大类型:控制信息的通信(低级通信)和大批数据信息的通信(高级通信).

    低级通信主要用于进程之间的同步,互斥,终止和挂起等等控制信息的传递.

    高级通信主要用于进程间数据块数据的交换和共享,常见的高级通信有管道,消息队列,共享内存等.

    进程通信的方式

    1)文件和记录锁定

    为避免两个进程间同时要求访问同一资源而引起访问和操作的混乱,在进程对共享资源进行访问前必须对其锁定,该进程访问完后再释放.这是UNIX为共享资源提供的互斥性保障.

    2)管道

    管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用.进程的亲缘关系一般指的是父子关系.管道一般用于两个不同进程之间的通信.当一个进程创建了一个管道,并调用fork创建自己的一个子进程后,父进程关闭读管道端,子进程关闭写管道端,这样提供了两个进程之间数据流动的一种方式.

    3)有名管道

    有名管道也是一种半双工的通信方式,但是它允许无亲缘关系进程间的通信.

    4)FIFO

    FIFO是一种先进先出的队列.它类似于一个管道,只允许数据的单向流动.每个FIFO都有一个名字,允许你不相关的进程访问同一个FIFO,因此也成为命名管.

    5)信号量

    信号量是一个计数器,可以用来控制多个线程对共享资源的访问.,它不是用于交换大批数据,而用于多线程之间的同步.它常作为一种锁机制,防止某进程在访问资源时其它进程也访问该资源.因此,主要作为进程间以及同一个进程内不同线程之间的同步手段.

    6)信号

    信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生.

    7)消息队列

    消息队列是消息的链表,存放在内核中并由消息队列标识符标识.消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等特点.消息队列是UNIX下不同进程之间可实现共享资源的一种机制,UNIX允许不同进程将格式化的数据流以消息队列形式发送给任意进程.对消息队列具有操作权限的进程都可以使用msget完成对消息队列的操作控制.通过使用消息类型,进程可以按任何顺序读信息,或为消息安排优先级顺序.

    8)共享内存

    共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问.共享内存是最快的IPC(进程间通信)方式,它是针对其它进程间通信方式运行效率低而专门设计的.它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步与通信.

    9)套接字(socket)

    套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同进程及其间进程的通信.

    通信方式的优缺点

    几种通信方法总结综上所述.进程之间的多种通信方法各自有各自的优点和缺点:如果用户传递的信息较少.或是需要通过信号来触发某些行为.前文提到的软中断信号机制不失为一种简捷有效的进程间通信方式.但若是进程间要求传递的信息量比较大或者进程间存在交换数据的要求,那就需要考虑别的通信方式了。无名管道简单方便.但局限于单向通信的工作方式.并且只能在创建它的进程及其子孙进程之间实现管道的共享:有名管道虽然可以提供给任意关系的进程使用.但是由于其长期存在于系统之中,使用不当容易出错.所以普通用户一般不建议使用。消息缓冲可以不再局限于父子进程.而允许任意进程通过共享消息队列来实现进程间通信.并由系统调用函数来实现消息发送和接收之间的同步.从而使得用户在使用消息缓冲进行通信时不再需要考虑同步问题.使用方便,但是消息队列中信息的复制需要额外消耗CPU的时间.不适宜于信息量大或操作频繁的场合共享内存针对消息缓冲的缺点改而利用内存缓冲区直接交换信息,无须复制,快捷、信息量大是其优点。但是共享内存的通信方式是通过将共享的内存缓冲区直接附加到进程的虚拟地址空间中来实现的.因此,这些进程之间的读写操作的同步问题操作系统无法实现。必须由各进程利用其他同步工具解决。另外,由于内存实体存在于计算机系统中.所以只能由处于同一个计算机系统中的诸进程共享,不方便网络通信不同的进程通信方式有不同的优点和缺点.因此.对于不同的应用问题,要根据问题本身的情况来选择进程间的通信方式。

    一般来说,进程间的通信根据通信内容可以划分为两种:即控制信息的传送与大批数据传送。有时也把进程间控制信息的交换称为低级通信,而把进程间大批量数据的交换称为高级通信。

    展开全文
  • 程序员必须让拥有依赖关系的进程集协调,这样才能...第一种技术具有通信依赖关系的两个进程间传递信息。这种技术称做进程间通信(interprocess communication)。第二种技术是同步,当进程间相互具有合作依赖时使用

    http://blog.csdn.net/liuzhanchen1987/article/details/7452910

    程序员必须让拥有依赖关系的进程集协调,这样才能达到进程的共同目标。可以使用两种技术来达到协调。第一种技术在具有通信依赖关系的两个进程间传递信息。这种技术称做进程间通信(interprocess communication)。第二种技术是同步,当进程间相互具有合作依赖时使用。这两种类型的依赖关系可以同时存在。

    一般而言,进程有单独的地址空间。我们可以了解下可执行程序被装载到内存后建立的一系列映射等理解这一点。如此以来意味着如果我们有两个进程(进程A和进程B),那么,在进程A中声明的数据对于进程B是不可用的。而且,进程B看不到进程A中发生的事件,反之亦然。如果进程A和B一起工作来完成某个任务,必须有一个在两个进程间通信信息和时间的方法。我们这里可以去看看基本的进程组件。注意进程有一个文本、数据以及堆栈片断。进程可能也有从自由存储空间中分配的其它内存。进程所占有的数据一般位于数据片断、堆栈片断或进程的动态分配内存中。数据对于其它进程来说是受保护的。为了让一个进程访问另外一个进程的数据,必须最终使用操作系统调用。与之类似,为了让一个进程知道另一个进程中文本片断中发生的事件,必须在进程间建立一种通信方式。这也需要来自操作系统API的帮助。当进程将数据发送到另一进程时,称做IPC(interprocess communication,进程间通信)。下面先列举几种不同类型的进程间通信方式:

    进程间通信                                 描述

    环境变量/文件描述符            子进程接受父进程环境数据的拷贝以及所有文件描述符。父进程可以在它的数据片断或环境中设置一定的变量,同时子进程接收这些值。父进程可以打开文件,同时推进读/写指针的位置,而且子进程使用相同的偏移访问该文件。

    命令行参数                      在调用exec或派生函数期间,命令行参数可以传递给子进程。

    管道                            用于相关和无关进程间的通信,而且形成两个进程间的一个通信通道,通常使用文件读写程序访问。

    共享内存                        两个进程之外的内存块,两个进程均可以访问它。

    DDE(动态数据交换,Dynamic data exchange)     使用客户机/服务器模型(C/S),服务器对客户的数据     或动作请求作出反应。

    一、环境变量、文件描述符:

    当创建一个子进程时,它接受了父进程许多资源的拷贝。子进程接受了父进程的文本、堆栈

    以及数据片断的拷贝。子进程也接受了父进程的环境数据以及所有文件描述符的拷贝。子进

    程从父进程继承资源的过程创造了进程间通信的一个机会。父进程可以在它的数据片断或环

    境中设置一定的变量,子进程于是接受这些值。同样,父进程也可以打开一个文件,推进到

    文件内的期望位置,子进程接着就可以在父进程离开读/写指针的准确位置访问该文件。

    这类通信的缺陷在于它是单向的、一次性的通信。也就是说,除了文件描述外,如果子进程

    继承了任何其它数据,也仅仅是父进程拷贝的所有数据。 一旦创建了子进程,由子进程对

    这些变量的任何改变都不会反映到父进程的数据中。同样,创建子进程后,对父进程数据的

    任何改变也不会反映到子进程中。所以,这种类型的进程间通信更像指挥棒传递。一旦父进

    程传递了某些资源的拷贝,子进程对它的使用就是独立的,必须使用原始传递资源。

    二、命令行参数:

    通过命令行参数(command-line argument)可以完成另一种单向、一次性的进程间通信

    我前面的文章已经提到过使用命令行参数。命令行参数在调用一个exec或派生调用操作系

    统时传递给子进程。命令行参数通常在其中一个参数中作为NULL终止字符串传递给exec

    或派生函数调用。这些函数可以按单向、一次性方式给子进程传递值。WINDOWS有调用执行

    exe程序的API。大家可以去参考一下ShellExecuteA函数相关。

    三、管道通信:

    继承资源以及命令行参数是最简单形式的进程间通信。它们同时有两个主要限制。除了文件

    描述符外,继承资源是IPC的单向、一次性形式。传递命令参数也是单向、一次性的IPC

    方法。这些方法也只有限制于关联进程,如果不关联,命令行参数和继承资源不能使用。还

    有另一种结构,称做管道(Pipe),它可以用于在关联进程间以及无关联进程间进行通信。

    管道是一种数据结构,像一个序列化文件一样访问。它形成了两个进程间的一种通信渠道。

    管道结构通过使用文本和写方式来访问。如果进程A希望通过管道发送数据给进程B,那么

    进程A向管道写入数据。为了让进程B接收此数据,进程B必须读取管道,与命令行参数的

    IPC形式不一样。管道可以双向通信。两进程间的数据流是双向通信的。管道可以在程序的

    整个执行期间使用,在进程间发送和接收数据。所以,管道充当可访问管道的进程间的一种

    可活链接,有两种基本管道类型:

    1.  匿名管道

    2.  命名管道

    匿名管道

    上面的图可以看出在没有管道时,两进程是不能互写的。

    匿名管道

    建立管道后就可以相互通信了。

    只有关联进程可以使用匿名管道来通信。无关联进程必须使用命名管道。

    匿名管道:通过文件描述符或文件句柄提供对匿名管道的访问。对系统API的调用创建一个管道,并返回一个文件描述符。这个文件描述符是用作read()或write()函数的一个参数。当通过文件描述符调用read()或write()时,数据的源和目标就是管道。例如,在OS/2环境中使用操作系统函数DosCreatePipe()创建匿名管道:

    int mian( void )

    {

        PFHILE readHandle;

    PFHILE writeHandle;

    DosCreatePipe( readHandle, writeHandle, size );

    }

    在WINDOWS下例如我写的ASM集成环境通过管道与DOS命令行通信的MFC下代码块:

    void CIDEManager::Commond( CString cmd, char* buf, unsigned int bufsize )

    {

        SECURITY_ATTRIBUTES sa;

        HANDLE hRead, hWrite;

        sa.nLength              = sizeof( SECURITY_ATTRIBUTES );

        sa.lpSecurityDescriptor = NULL;

    sa.bInheritHandle       = TRUE;

        if ( !CreatePipe( &hRead, &hWrite, &sa, 0 ) )  // 创建管道

        {

            return;

        }

        STARTUPINFO si;

        PROCESS_INFORMATION pi;

        si.cb = sizeof( STARTUPINFO );

        GetStartupInfo( &si );

        si.hStdError   = hWrite;

        si.hStdOutput  = hWrite;

        si.wShowWindow = SW_HIDE;

        si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

    if ( !CreateProcess( NULL, ( LPTSTR )( LPCTSTR )cmd, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi ) )

        {

            return;

        }

        CloseHandle( hWrite );

        DWORD bytesRead;

        while ( TRUE )

        {

            memset( buf, 0, bufsize );

            if ( ReadFile( hRead, buf, bufsize, &bytesRead, NULL ) != NULL )

            {

                break;

            }

            Sleep( 200 );

        }

        CloseHandle( hRead );

        return;

    }

    命名管道:将管道用作两个无关联进程间的通信渠道,程序员必须使用命名管道,它可以看作一种具有某名字的特殊类型文件。进程可以根据它的名字访问这个管道。通过匿名管道,父和子进程可以单独使用文件描述符来访问他们所共享的管道,因为子进程继承了父进程的文件描述符,同时文件描述符用read()或write()函数的参数。因为无关进程不能访问彼此的文件描述符,所以不能使用匿名管道。由于命名管道提供该管道的一个等价文件名,任何知道此管道名字的进程都可以访问它。下面是命名管道相对于匿名管道的优点:

    命名管道可以被无关联进程使用。

    命名管道可以持久。创建它的程序退出后,它们仍然可以存在。

    命名管道可以在网络或分布环境中使用。

    命名管道容易用于多对一关系中。

    与访问匿名管道一样,命名管道也是通过read()或write()函数来访问。两者之间的主要区别在于命名管道的创建方式以及谁可以反问它们。命名管道可以建立一个进程间通信的C/S模型。访问命名管道的进程可能都位于同一台机器上,或位于通过网络通信的不同机器上。由于管道的名字可以通过管道所在服务器的逻辑名,所以能够跨网络访问管道。例如,ServerName//Pipe//MyPipe(不区分大小写)可以作为一个管道名字。假如Server1是网络服务器的名字。当打开或访问这个管道的调用解析文件名时,首先应该定位Server1,然后访问MyPipe。例子如下:

    服务器端:

    int main( void )

    {

        HANDLE pipehandle;

        char buf[ 256 ];

    DWORD bytesRead;

          if( ( pipehandle = CreateNamedPipe( ".//Pipe//cao", PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1, 0, 0, 5000, NULL ) ) == INVALID_HANDLE_VALUE )

        {

            printf( "CreateNamedPipe failed with error %d/n", GetLastError() );

            system( "pause" );

            return 0;

        }

        printf( "server is running/n" ); 

        if( ConnectNamedPipe( pipehandle, NULL ) == 0 )

        {

            printf( "connectNamedPipe failed with error %d/n", GetLastError() );

            CloseHandle( pipehandle );

            system( "pause" );

            return 0;

        }    

        if( ReadFile( pipehandle, buf, sizeof( buf ), &bytesRead, NULL ) == 0 )

        {

            printf( "ReadFile failed with error %d/n", GetLastError() );

            CloseHandle( pipehandle );

            system( "pause" );

            return 0;

        }

        printf( "%s/n", buf );      

        if ( DisconnectNamedPipe( pipehandle ) == 0 )

        {

            printf( "DisconnectNamedPipe failed with error %d/n", GetLastError() );

            CloseHandle( pipehandle );

            system( "pause" );

            return 0;

        }

        system( "pause" );

        return 0;

    }

    客户端:

    int main( void )

    {

        HANDLE pipehandle;

        DWORD writesbytes;

        char buff[ 256 ];

        if( WaitNamedPipe( ".//Pipe//cao", NMPWAIT_WAIT_FOREVER ) == 0 )

        {

            printf( "WaitNamedPipe failed with error %d/n", GetLastError() );

            system( "pause" );

            return 0;

        }

         if( ( pipehandle = CreateFile( ".//Pipe//cao", GENERIC_READ | GENERIC_WRITE, 0, ( LPSECURITY_ATTRIBUTES )NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, ( HANDLE )NULL ) ) == INVALID_HANDLE_VALUE )

        {

            printf( "CreateFile failed with error %d/n", GetLastError() );

            system( "pause" );

            return 0;

        }

        ZeroMemory( &buff, sizeof( buff ) );

        gets( buff );

        if( WriteFile( pipehandle, buff, sizeof( buff ), &writesbytes, NULL ) == 0 )

        {

            printf( "WriteFile failed with error %d/n", GetLastError() );

            CloseHandle( pipehandle );

            system( "pause" );

            return 0;

        }    

        printf( "write %d bytes", writesbytes );

        CloseHandle( pipehandle );

        system( "pause" );

        return 0;

    }

    命名管道不仅可用于无关联进程间、位于不同机器上的两进程间的通信,而且可用于多对一通信,可以建立服务器进程,允许同时通过多个客户访问命名管道。命名管道常常用于多线程服务器。

    四、 共享内存

    共享内存也可以实现进程间的通信。进程需要可以被其他进程浏览的内存块。希望访问这个内存块的其他进程请求对它的访问,或由创建它的进程授予访问内存块的权限。可以访问特定内存块的所有进程对它具有即时可见性。共享内存被映射到使用它的每个进程的地址空间。所以,它看起来像是另一个在进程内声明的变量。当一个进程写共享内存,所有的进程都立即知道写入的内容,而且可以访问。

    进程间共享内存的关系与函数间全局变量的关系相似。程序中的所有函数都可以使用全局变量的值。同样,共享内存块可以被正在执行的所有进程访问。内存块可能共享一个逻辑地址,进程也可以共享某些物理地址。

    共享内存块的创建必须由一个系统API调用来完成。在WIN32环境中,使用CreateFileMapping()、MapViewOfFile()以及MapViewOfFileEx() API能很好地完成。

    共享内存分配位于WIN32系统中2~3GB地址范围内。一旦调用MapViewOfFile()和MapViewOfFileEx(),共享文件映射对象的所有进程都可以立即访问此内存块,而且在需要时,可以读写此内存块。

    五、动态数据交换

    动态数据交换( dynamic data exchange ) 是当今可用的进程间通信最强大和完善的形式之一。动态数据交换使用消息传递、共享内存、事务协议、客户/服务器范畴、同步规则以及会话协议来让数据和控制信息在进程间流动。动态数据交换对话( dynamic data exchange session, DDE )的基本模型是客户、服务器。服务器对来自客户的数据或动作作出反应。客户和服务器可以以多种关系来通信。

    一个服务器可以与任意数量的客户通信。一个客户也可以与任意数量的服务器通信。单个DDE代理既可以是客户,也可以是服务器。也就是说,进程可以从一个正为另一个进程执行服务的DDE代理请求服务。

     

    展开全文
  • 随着物联网新兴技术的发展, 蓝牙、Wi-Fi、NFC、ZigBee是大家非常熟悉的无线通信技术。...很多通信协议可用于物联网网关与云服务器之间的通信。 这里由朗锐智科(www.leadtorch.com) 介绍一些比较热门的技术及其...
  • 进程通信的含义 进程是转入内存并准备...由于不同的进程运行各自不同的内存空间中,其中一个进程对于变量的修改另一方是无法感知的,因此,进程之间的消息传递不能通过变量或其他数据结构直接进行,只能通过进程间通
  • 扩频通信由于具有抗干扰能力强,隐蔽性好,容易实现多址传输等优点移动通信、无线数据通信等领域得到越来越广泛的应用。其中直接序列扩频通信是目前使用最典型的扩频工作方式。
  • 做vue项目中,组件之间的通信是必不可少的,但是vue多少种方式、用法、优缺点及适用场景,本篇文章大概总结一下。(本篇摘抄[Vue组件通信方式及其应用场景总结](https://juejin.cn/post/6903796293445877773)并...
  • 直接序列扩频通信系统(DS-CDMA)因其抗干扰性强、 隐蔽性好、易于实现码分多址(CDMA)、抗多径干扰、直扩通信速率高等众多优点,而被广泛应用于许多领域中。针对频通信广泛的应用,本文用MATLAB工具箱中的...
  • 直接扩频通信具有低截获概率、抗干扰能力强以及易于实现码分多址等优点抗干扰通信及民用移动通信中都得到了广泛的应用。 仿真流程图 用户1扩频加扰调制高斯信道walsh码扩频M序列加扰载波调制高斯白噪声高斯信道...
  • 为了了解部署过程中出现的情况,silicon.com对已经部署过统一通信系统的CIO和IT主管进行了采访,希望了解整个过程的具体情况以及需要进行的准备工作哪些。 优点1 根据专家的说法,整个部署过程中没有出现...
  • 进程间通信方式以及各自的优缺点

    千次阅读 2016-12-04 21:21:21
    无名管道是一种半双工的通信方式,数据只能单向流动,而且只能具有亲缘关系的进程间使用.进程的亲缘关系一般指的是父子关系。无明管道一般用于两个不同进程之间的通信。当一个进程创建了一个管道,并调用fork创建自己...
  • 点到点与端到端通信有什么区别:

    千次阅读 2019-01-21 22:45:05
    点到点是网络层的,你传输层只认为我的数据是从a直接到e的,但实际不是这样的,打个比方,传输层好象领导,他发布命令:要干什么什么事,但真正干的不是他,真正干的是员工,也许领导认为很简单一句话就可以...
  • 2、管道:管道分为有名管道和无名管道,其中无名管道是一种半双工的通信方式,数据只能单向流动,而且只能具有亲缘关系的进程间使用,一般用于两个不同进程之间的通信。有名管道也是一种半双工的通信方式,但它...
  • a、使用socket通信的方式实现起来简单,可以使用因特网域和UNIX域来实现,使用因特网域可以实现不同主机之间的进出通信。 b、该方式自身携带同步机制,不需要额外的方式来辅助实现同步。 c、随进程持续。 共享...
  • 端到段、点到点通信的区别 优缺点

    千次阅读 2015-08-21 21:23:40
    端到端传输指的是数据传输前,经过各种各样的交换设备,两端设备问建立一条链路,就僚它们是直接相连的一样,链路建立后,发送端就可以发送数据,直至数据发送完毕,接收端确认接收成功。 点到点系统指的是...
  • # 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。 # 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它...
  • 三种射频通信接收机原理框图及优缺点

    万次阅读 多人点赞 2019-03-20 22:18:00
    目录 1.超外差接收机SuperHeterodyne Receiver ...典型的超外差式接收机的如图,振荡器产生一个始终比接收信号高一个中频频率的振荡信号,混频器将振荡信号与接收信号相减产生一个新的频率即中频,这就是“...
  • 直接序列扩频通信系统的扩频增益受限,强功率的窄带干扰对其性能影响较大,为了提高系统的通信效果,需要采取信号处理技术来抑制干扰。笔者对可调谐数字外差滤波器进行了改进。提出了应用于直接序列扩频通信系统中的...
  • 摘要: 直接序列扩频通信系统(DS-CDMA)因其抗干扰性强、 隐蔽性好、易于实现码分多址(CDMA)、抗多径干扰、直扩通信速率高等众多优点,而被广泛应用于许多领域中。本设计中首先首先对于直接扩频及PSK调制解调基本...
  • 无线通信模块种类和优点

    千次阅读 2020-07-03 14:34:50
    1、无线数传模块,这种模块厂家已经做了单片机,并且写好了无线通信部分的程序,可直接通过串口收发数据,使用简单,当相对来说成本也比较高。 2、无线收发模块,一般要通过单片机控制无线收发数据,一般为FSK、GFSK...
  • 优点 缺点 适用场景 Bundle 简单易用 只能传输Bundle支持的数据类型 四大组件间的进程间通信 文件共享 简单易用 不适合搞并发场景,并且无法做到进程间的即时通信 无并发访问情形,...
  • 扩频通信可使信噪比改善20到50多分贝,而且具有抗噪声、抗干扰、抗衰落、抗多径能力强,可以采用三分多址实现多址通信,易于多媒体通信组网,具有良好的安全通信能力等诸多优点,已民用和军事中被广泛应用。...
  • 无名管道是一种半双工的通信方式,数据只能单向流动,而且只能具有亲缘关系的进程间使用,进程的亲缘关系一般指的是父子关系。无名管道一般用于两个不同进程之间的通信。 当一个进程创建了一个管道,并调用fork...
  • 直接数字频率合成(DDS)技术是从相位概念出发直接合成所需波形的一种新的频率合成技术,具有频率分辨率高、频率变换速度快、相位可连续线性变化等优点基于数字信号处理的现代通信频率控制中已被广泛采用。...
  • 腾讯云音视频SDK的调研报告之优缺点     缺点   优点               2015/05/20腾讯云正式对外开放QQ音视频,此项服务目前推出时间算是比较短,使用其SDK且有所名气的App目前市场上还几乎没有看到。...
  • 结果面试过程只花了 5 分钟就结束了,面完的时候,天还是依然是亮的,还得烈日下奔波 1 小时回去。 面试五分钟,骑车两小时。 你看,张三因面试没准备好,吹空调的时间只有 5 分钟,来回路上花了 2 小时晒太阳,你...
  • 目前使用较广泛的近距无线通信技术是蓝牙(Bluetooth),无线局域网802.11(Wi-Fi)和红外数据传输(IrDA)。同时还有一些具有发展潜力...它们都其立足的特点,或基于传输速度、距离、耗电量的特殊要求;或着眼于功能的扩充
  • 前篇见此: 操作系统清华大学版笔记(十) 信号量、管程...进程间通信死锁、死锁模型、死锁预防和恢复、银行家算法死锁:一组阻塞的进程(两个或多个),持有一种资源,等待获取另一个进程所占有的资源,而导致谁都无

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 205,438
精华内容 82,175
关键字:

在直接通信有什么优缺点