• 几种进程间的通信方式


    转自:http://www.cnblogs.com/mydomain/archive/2010/09/23/1833369.html

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

     
    昨天总结了一些进程之间的通信方式,其实就是给一些函数做了基本的用法记录,今天看了看还是好好的看一下这

    几个的区别。

    几种方式:

    文件、管道、共享内存空间:

    1.文件方式的进程通信就是通过读写同一个文件来完成共享数据。一个进程将数据写入文件,另一个进程再将

    数据从文件中读出。

    客户端能够读取文件,且能够多个客户端同时读取,系统允许同时打开一个文件。

    服务器端通过清空重写的方式对文件内容进行修改

    问题:不能避免在文件尚未进行完写操作时就有进程读取文件内容,这时会造成读取的文件内容为空或者是读

    出文件中的部分数据。

    解决方案:可以通过文件锁的方式进行控制。


    2.命名管道:常规的管道只能连接相关进程,由进程创建并由最后一个进程关闭。而命名管道可以连接不相关

    的进程。它是个FIFO先进先出队列,即使没有进程,命名管道依然可以存在,它不依赖于进程。服务器将字节

    写入队列,客户端从队列头部移出字节。服务器必须重写数据。它没有竞争的问题,在没有超过管道最大长度

    的时候,read和write都是原子操作,先将管道清空,然后再将管道写满,在读者和写者联通之前系统内核将

    进程刮起。

    共享内存段:不依赖于进程的存在而存在。共享内存段拥有权限系统来控制进程各自的访问权限。多个客户端

    都可以同时从内存中读数据。

    问题:如果读取是在服务器向内存中写数据的时候进行的,有可能既读到旧数据又读到新数据。

    解决方案:信号量机制。


    比较:

    1.文件和命名管道消耗操作多。

    2.文件和共享内存是无连接的

    3.命名管道和共享内存只能在本机中使用

    4.使用共享内存和文件要比使用管道麻烦,要处理竞态。


    进程的产生:

    1.进程号:
    getpid()---当前进程id
    getppid()---父进程id

    2.fork()---复制进程,子进程id与父进程id不同,内存等与父进程不同,其他与父进程共享。

    3.system()---当这个函数中的命令执行完毕之后才能继续本进程,也就是说它可以阻塞本进程。

    4.exec()函数系列---新进程代替原进程,只有id与原id相同。
     ---普遍用法:使用fork()分岔进程,在新进程中调用exec()函数,这样exec()就占用了原来系统资源来运行(id没换但内容换了,挂得还是羊头卖得却是狗日)

    5.init---进程都是有init直接或间接fork()出来的。

    进程间的通信:

    1.管道:

    int pipe(int filedes[2])---创建管道,如进程A、B,则每个进程都有读和写两个描述符,在通信的时候关闭不用的那个。

    命名管道 mkfifo

    2.消息队列:

    ftok()---键值构造函数,下面的函数需要这里的键值

    msgget()---创建一个消息队列或者访问一个现有队列。

    msgsnd()---向队列传递消息

    msgrcv()---接收消息队列中的消息

    msgclt()---向内核发送一个cmd命令,内核根据此来判断进行何种操作。


    信号量:控制多个进程共享资源的访问。

    semget()---新建信号量,返回信号的id

    semmlt()---发送命令建立value个初始值的信号量

    semop()---向信号量发送命令

    semctl()---信号量控制的其他操作

    共享内存:通过共享内存区域实现进程之间的通信

    shmget()---创建一个新的共享内存段或者访问一个现有的共享内存段,返回段标识符

    shmat()---获取共享内存的地址

    shmdt()---删除,实际上是断开,断开后shmid_ds的shm_nattch-1,当==0时真正的删除内存段

    shmctl()---对共享内存的控制

    信号:最为古老的进程之间的通信方式

    进程可以屏蔽大多数信号,除了SIGSTOP SIGKILL

    signal()---信号获取函数,对此信号挂接用户自己的处理函数

    很明显,上面这些很多函数的名字都是有规律可循的,用法也差不多……

    好了,明天继续---线程

    http://www.cnblogs.com/wanpengcoder/archive/2010/07/16/1778552.html

  • 相关阅读:
    c++ primer plus 第六章 课后题答案
    动态创建easyui控件的渲染问题
    晨报
    动态构建easyUI grid
    早起
    周末
    js ajax方式拼接参数
    5个月
    锻炼
    东湖夜色
  • 原文地址:https://www.cnblogs.com/wuyuankun/p/3687392.html
Copyright © 2020-2023  润新知