linux操作系统-3进程管理(3)

来源:互联网 发布:ubuntu变为中文 编辑:程序博客网 时间:2024/05/22 05:33

LINUX下进程间通信IPC

在LINUX内核中,进程各自的用户地址空间是相互独立的。支持POSIX规范中标准的IPC。

1、管道

使用简单,局限性:半双工,即一条管道中数据只能单一方向流动。

管道两端的进程必须是父子关系或具有相同的祖先

使用模式:进程通过系统调用pipe(int fd[2])创建一条管道,返回0代表系统调用成功。fd[0]赋值为管道读端,fd[1]赋值为管道写端。进程调用fork()系统调用创建一个新的子进程。

在linux内核中,管道是借助于管道文件系统(pipefs)来实现的。在文件系统的inode结构中,有一个指向struct pipe_inode_info类型的指针i_pipe,这样就把文件系统与管道联系起来。

2、命名管道

FIFO,是一种特殊的文件(类型为S_IFIFO)在文件系统中真实存在。两个或多个进程可以同时打开并读写FIFO文件以达到进程通信的目的。进程操作FIFO文件方法与操作普通文件的方法完全相同。是一种双向的进程间通信机制。

实现与管道的类似处是,都是通过pipefs文件系统来完成的,不同之处是管道是通过Pipe系统调用创建的,所以当管道的文件描述符关闭或相关的进程退出后管道就不存在了;而FIFO是通过mknod系统调用创建的,因而在虚拟文件系统中真实存在一个FIFO文件。所谓命名管道就是利用文件系统(FIFO文件的Inode)建立起与管道缓冲区的映射,避免管道对于父子进程或相关进程的限制。

3、消息队列

管道和FIFO局限性是仅仅提供了基本的通信方法,用户如果真正使用它们传送消息,还需要自己定义消息的格式、大小并保证消息的完整性。另外,只能顺序读写。最后管道要求通信的双方都要同时连接在管道的两端(否则会接到SIGPIPE错误信号)。

消息队列可以看成是消息的链表,用来提供进程间简短信息的传递。

LINUX内核实现了系统五和POSIX规范两种形式的消息队列。

1)sys V

消息队列在内核中创建了消息的链表,每个消息队列有一个唯一的队列标示msgid,应用程序可以使用msgget系统调用来打开或创建一个消息队列并得到相应的标识。消息队列提供的一个重要特征就是消息的分类。在发送和接收消息的时候都可以指定消息类型。系统五消息队列消息的分类机制是在接收端实现的。

2)POSIX

与系统五相比,增加:

简化了基于文件的接口;

增强的消息优先级支持;

异步消息机制,并可指定通过信号处理函数或创建新的进程来处理消息;

可设置超时的可阻塞的消息发送和接收方法。

mq_open()打开队列,mq_send(),mq_receive(),mq_close()

LINUX内核通过mqueue文件系统实现POSIX消息队列。借助虚拟文件系统。

4、共享内存

同一块物理内存分别映射到不同进程的虚拟地址空间来实现数据的交换。由于数据不需要在进程和进程之间复制,因此在理论上这是一种最快速的IPC机制。

shmget系统调用创建一个新的或者取得一个已经建立的共享内存标识shmid,使用shmat系统调用把由shmid标识的共享内存片段映射到调用进程的虚拟地址空间中,接下来就可以像操作普通虚拟内存那样操作这块共享内存进程操作。最后使用完毕后还要调用shmat系统调用释放共享内存的映射。若需要释放共享内存本身,shmctl系统调用(加命令选项IPC_RMID)来完成。

共享内存是通过shm文件系统实现的。

共享内存虽然具有使用简单、传输速度快等优点,但对于给定存储空间的内容却没有任何保护(由于共享内存的访问与普通内存操作相同),信号量作为一种常见的同步机制被用来完成对共享内存读写的保护

(转载)1.信号量的定义:

信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。

Semaphore分为单值和多值两种前者只能被一个线程获得,后者可以被若干个线程获得

以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。

在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。

抽象的来讲,信号量的特性如下:信号量是一个非负整数(车位数),所有通过它的线程/进程(车辆)都会将该整数减一(通过它当然是为了使用资源),当该整数值为零时,所有试图通过它的线程都将处于等待状态。在信号量上我们定义两种操作: Wait(等待) 和 Release(释放)。当一个线程调用Wait操作时,它要么得到资源然后将信号量减一,要么一直等下去(指放入阻塞队列),直到信号量大于等于一时。Release(释放)实际上是在信号量上执行加操作,对应于车辆离开停车场,该操作之所以叫做“释放”是因为释放了由信号量守护的资源。

信号量,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。


5、套接口

socket不但支持在同一台主机上的进程间通信,还支持不同主机上的进程间通信。根据使用域可以分为网络套接口UNIX域套接口。前者可用于不同主机上的进程间通信,而后者只能用于同一主机上的进程间通信。


0 0
原创粉丝点击