IPC(Inter-Process Communication,进程间通信)对象数据结构:
内核为每个IPC对象维护一个数据结构
structipc_perm {
key_t __key; /* Key supplied to xxxget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions */
unsigned short __seq; /* Sequence number */
};
IPC对象的持续性:
随进程持续:一直存在直到打开的最后一个进程结束。(如pipe和FIFO)
随内核持续:一直存在直到内核自举或显式删除(如System V消息队列、共享内存、信号量)
随文件系统持续:一直存在直到显式删除,即使内核自举还存在。(POSIX消息队列、共享内存、信号量如果是使用映射文件来实现)
消息队列:
消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法;
每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值;
消息队列也有管道一样的不足,就是每个消息的最大长度是有上限的(MSGMAX),每个消息队列的总的字节数是有上限的(MSGMNB),系统上消息队列的总数也有一个上限(MSGMNI)
共享内存:
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。
信号量:
信号量和P、V原语由Dijkstra(迪杰斯特拉)提出
信号量
互斥:P、V在同一个进程中
同步:P、V在不同进程中
信号量值含义
S>0:S表示可用资源的个数
S=0:表示无可用资源,无等待进程
S<0:|S|表示等待队列中进程个数
structsemaphore
{
intvalue;
pointer_PCBqueue;
}
P原语:
P(s)
{
s.value = s.value--;
if (s.value < 0)
{
该进程状态置为等待状状态
将该进程的PCB插入相应的等待队列s.queue末尾
}
}
V原语:
V(s)
{
s.value = s.value++;
if (s.value < =0)
{
唤醒相应等待队列s.queue中等待的一个进程
改变其状态为就绪态
并将其插入就绪队列
}
}