您的位置:首页 > 运维架构 > Linux

linux IPC简单学习

2016-03-08 19:22 549 查看

Posix和system v区别

所谓的IPC(进程间通信)指的是消息队列,共享内存,信号量3种机制合并起来,当然,这是个狭义的概念,只包含这三种。IPC又可以分为system v进程间通信和posix进程间通信。

下图说明了各种概念之间的关系。



IPC机制的作用范围是在整个系统,而不是仅限于进程,也就是说,一旦IPC对象被创建,除非显示的删除或者系统重启,否则对象一直存在,其中数据也保持不变。而进程打开的文件会在进程退出后自动关闭。



消息传递

管道

从本质上看,管道也是一种文件,只不过这种文件比较特殊。其有以下几种特点:

1)管道的数据流是单向的,只能由写入端向读出端

2)管道中的数据先进先出。

3)管道有大小限制,linux下,大小为4096字节。

1.普通管道:位于内存,只能由有亲缘关系的进程间通信

2.命名管道:位于文件系统中,可以实现不同进程间的通信。

消息队列

队列是一个受限的线性表,需要按照先进先出的方式进行。

消息就是进程间传递数据的内容。在消息队列机制中,消息是有类型的,对于一个同一个消息队列来说,可以存储不同类型的消息,而进程可以根据自己的需要从消息队列中取出自己感兴趣的消息。

消息的类型有一个结构模板,模板的名称是struct msgbuf,其定义位于<sys/msg.h>,结构定义如下所示。

Struct msgbuf
{

Long int mytype;

Char mtext[1];

}

消息队列有以下特征:

1.消息队列中的消息是有类型的,再发送一条信息的时候,可以指定消息类型。在接受进程中,可以按照该消息类型从消息队列中获取数据。在实际应用中,可以多个应用共用一个队列,用消息类型区分不同的应用。

2.消息队列中的消息按照发送的顺序排队,对于相同类型的消息,先进入消息队列的消息先被接受。

限制:系统中最多允许16个消息队列。每条消息的最大字节数为8192,每个队列最多可容纳字节数是16384。

使用流程:

1.使用ftok获得一个键值。

2.根据键值申请消息队列,如果消息队列以经存在,则再次以第二个参数为零申请。

3.可以发送信息了,信息的类型是void

4.别忘了删除啊~~~~

消息队列的数据流的过程为:将数据复制到内核分配的缓冲区,接受进程再从内核的缓冲区复制到进程的虚拟地址空间。

共享内存

共享内存视同过将内核的缓冲区映射到进程的地址空间实现的,没有数据复制的过程,所以速度比消息队列要快。成功映射后读写共享内存就像读写进程变量一样高速。

使用一块共享内存的步骤:

1.申请键值

2.申请共享内存

3.映射共享内存

4.可以读写了

5.别忘了删除

同步

信号量

信号量为什么也要算到进程间通信呢,因为它可以配合共享内存使用,实现多个进程之间共享资源的保护。包括文件的共享也可以用信号量。

P和v是原语,任何中断都不能中断原语的执行过程。

信号量不一定只支持两个县城,只支持两个线程叫互斥信号量。

互斥锁和条件变量

感觉互斥锁

互斥锁指代相互排斥,他是最基本的同步形式。互斥锁用来保护临界区。如果有多个线程被阻塞在等待同一个互斥锁上,那么解锁之后各种锁和信号量将唤醒优先级最高的函数。

条件变量是用来等待。

问题:现在的问题是互斥锁已经可以用来等待了,为什么还需要条件变量呢?

答:因为条件变量可以用来达到一种等待的优化

首先,用来发送信号让等待的线程取消等待的不一定是上锁的线程,在这点上它和信号量有区别。

其次,即使没人上锁,线程也不一定能获得这个锁。

比如写的那个文件传输系统,并不是没人上锁就可以获得这个锁了,没人上锁且线程池中没任务仍然要等待。而发送信号取消等待的线程是添加任务的线程,它并没有上锁。所以互斥锁和条件变量在一起的时候上锁和发送信号解锁的操作不一定同时出现。

问题:信号量和互斥锁的区别。

答:

1.信号量是进程或线程间,而互斥锁一般用在线程间。

2.互斥锁非0即1,和互斥信号量类似。

3.信号量是IPC概念,作用域为整个系统,而互斥锁则在进程之内。

4.信号量是互斥,互斥锁是同步。同步包含了互斥的功能,但作用更大。

自旋锁

自旋锁不会引起调用者的睡眠,如果一个线程试图获得一个已经被持有的自旋锁,那么该线程就会一直忙着循环,一直等待下去,在那里看看是否该自旋锁的保持锁已经释放了锁。

自旋锁也是0-1.

适用于保持时间比较短,如果自旋锁的占用时间不会超过两次上下文切换,就应该使自旋锁(在多cpu领域)。而且信号量的初始化时间较长。

读写锁

读写锁实际上是一种特殊的自旋锁。

他把对资源的访问者分为了读者和写者,使用规则如下:

1.只要没有使用者把持有的锁用于写,那么任意数目的用户都可以持有该锁用于读。

2.仅仅当没有线程持有某个给定的读写锁用于读或者用于写,才能分配该锁用于写。

其他

信号

来自为知笔记(Wiz)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: