学习Linux C编程之进程间通信(一)

来源:互联网 发布:通达信mac版划线工具 编辑:程序博客网 时间:2024/05/17 05:12

Linux进程间通信的目的:
数据传输:一个进程需要将他的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间;
共享数据:多个进程想要共享数据,一个进程对共享数据的修改,别的进程应该立刻看到;
通知事件:一个进程需要向另一个或一组进程发送消息,通知它发生了某种事件(如进程终止前要通知父进程);
资源共享:多个进程之间共享同样的资源。为了做到这一点,需要内核提供锁和同步机制;
进程控制:有些进程希望完全控制另一个进程的执行,此时控制进程希望能够拦截另一个进程的所有信息和异常,并能够及时知道它的状态。
 
常见的通信方式:
1. 管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
2. 命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
4. 消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
5. 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
6. 信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
7. 套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
8. 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。


管道通信的特点是:
1.管道是半双工的,数据只能向一个方向流动,需要双方通信时,需要建立两个管道。
2.只能同于父子进程或兄弟进程之间
3.单独构成一种文件系统,管道对于两端的进程而言,就是一个文件,但他不是普通的文件,不属于某种文件系统,而是自立门户,并且只存在于内存中。
4.数据的读入和写入,一个进程写的内容被另一端的进程读出,写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓存区的头部读出数据。
消息队列与管道、有名管道相比的优缺点
消息队列具有更大的灵活性,首先它提供格式字节流,有利于减少开发人员的工作量,其次消息具有类型,在实际应用中,可以作为优先级使用,这两点是管道和有名管道所不能比的。同样,消息队列可以在几个进程间复用,而不管这几个进程是否具有血缘关系,这一点与有名管道相似,但消息队列是随内核持续的,与有名管道相比(随进程持续),生命力更强,应用空间更大。


共享内存:
共享内存是运行在同一台机器上的进程间通信最快的方式,因为数据不需要在不同的进程间复制。通常由一个进程创建一块共享内存区,其余进程对这块内存区进行 读写。得到共享内存有两种方式:映射/dev/mem设备内存映像文件前一种方式不给系统带来额外的开销,但在现实中并不常用,因为它控制存取的将是 实际的物理内存,在Linux系统下,这只有通过限制Linux系统存取的内存才可以做到,这当然不太实际。常用的方式是通过shmXXX函数族来实现利 用共享内存进行存储的。 
首先要用的函数是shmget,它获得一个共享存储标识符。 
   #include <sys/types.h> 
  #include <sys/ipc.h> 
   #include <sys/shm.h> 
   int shmget(key_t key, int size, int flag); 
这个函数有点类似大家熟悉的malloc函数,系统按照请求分配size大小的内存用作共享内存。Linux系统内核中每个IPC结构都有的一个非负整数 的标识符,这样对一个消息队列发送消息时只要引用标识符就可以了。这个标识符是内核由IPC结构的关键字得到的,这个关键字,就是上面第一个函数的 key。数据类型key_t是在头文件sys/types.h中定义的,它是一个长整形的数据。在我们后面的章节中,还会碰到这个关键字。 


原创粉丝点击