标签:大小 struct stat 个数 sigpipe fat 物理内存 怎么 虚拟内存
进程间通信原因首先先谈谈管道和共享内存
管道---匿名管道,命名管道
本质:管道其实就是一块内存,是内核当中的缓冲区
原子性:当前操作不被打断,换句话说,在管道的读写操作是不可以被打断的
临界资源:同一时间,当前资源只能被一个进程所访问
互斥:同一时间,保证只能有一个进程访问临界资源
同步:保证临界资源访问的合理性
创建一个管道(亲缘关系的进程中使用)
int pipe(int pipefd[2]);
pipefd[0]:从pipefd[0]文件描述符中去读
pipefd[1]:从pipefd[1]文件描述符中去写
返回值:0(成功) -1(失败)
int fd[2];
int ret = pipe(fd);
if(ret != 0)
{
perror("pipe");//创建错误
return 0;
}
pid_t pid = fork();
if(pid < 0)
{
return 0;//创建失败
}
else if(pid == 0)//创建成功
{
//child
sleep(5);
close(fd[0]);
write(fd[1], "hehe", 4);
}
else
{
//father
close(fd[1]);
char buf[1024] = {0};
read(fd[0], buf, sizeof(buf));
printf("buf = %s\n", buf);
}
命名管道---有标识的管道
特性:
共享内存
原理:
创建共享内存的时候,首先在物理内存当中创建一块内存,各个进程都通过页表结构将该段内存映射到自己的虚拟内存地址空间上的共享区,各个进程通过映射的地址来进行通信
特性:
1.共享内存是最快的进程间通信方式
2.共享内存是不带有同步和互斥功能的
3.写入数据是按照覆盖的方式进行的
创建共享内存
int shmget(key_t key,size_t size,int shmflg)
key:共享内存标识符
size:共享内存的大小
shmflg:1.IPC_CREAT:如果共享内存不存在,则创建共享内存,如果已经存在,则返回
2.IPC_CREAT | IPC_EXCL如果共享内存依然存在,则报错,如果不存在则创建
3.+权限:按位或权限,权限相当于文件的权限(使用8进制的数字)
返回值:
成功返回共享内存的操作句柄
将进程附加到共享内存上
void *shmat(int shmid,const void *shmaddr,int shmflg);
shmid:共享内存的操作句柄
shmaddr:映射到共享区的地址,一般不选择(填NULL),由操作系统自己映射到虚拟地址空间
shmflg:0:可读可写 IPC_RDONLY:只读
返回值:
返回映射到的那个地址
分离进程和共享内存
int shmdt(const void *shmaddr);
shmaddr:shmat返回的地址
返回值:
成功返回0,失败返回1
共享内存的销毁
int shmctl(int shmid,int cmd,struct shmid_ds *buf);
shmid:共享内存的操作句柄
cmd:要使用什么操作
IPC_STAT:获取当前共享内存的状态,要搭配shmid_ds一起使用
IPC_RMID:删除共享内存,标记共享内存为删除状态
buf:一个出参,结构体当中是共享内存的一些信息
返回值:
失败返回-1
共享内存的生命周期
生命周期跟随操作系统内核
ipcs -m 查看共享内存
ipcrm -m [shmid] 删除一个共享内存
如果删除一个有进程的共享内存,操作系统的做法是,先标记当前的共享内存为destroy的状态,并且将key设置为0x00000000,表示当前的共享内存不能再被其他进程所附加,同时会释放内存,也就导致了正在附加到该共享内存上的进程有崩溃的风险,一般禁止这样去操作。当附加的进程退出的时候,操作系统就会将共享内存清除掉
消息队列
消息队列本质上是内核当中的一个优先级队列,进程通过访问优先级队列来增加节点或者查看节点,来进行进程间通信
特性:生命周期跟随进程,如果用户进程不删除消息队列资源,则资源一直在操作系统内核当中自带同步和互斥功能
接口:msgget/msgsnd/msgrcv/msgct
信号量-----计数器+PCB进程的等待队列
作用:实现进程的控制,也就是实现进程的同步和互斥
如何实现互斥?---PV操作
1.实现互斥的时候,信号量只有两个取值,也就是0或1,0表示当前资源不可用,1表示当前资源可用
2.当进程需要访问一个临界资源的时候,会先访问信号量,预计算信号量的值
先对当前信号进行预减1操作,判断当前信号是否小于0
如果是小于0,则表示信号量之前的值是等于0,则表示当前的临界资源不可用;将当前的进程放到PCB等待队列中去
如果是等于0,则表示信号量之前的值是等于1,则表示当前的临界资源可用;访问临界资源,并且信号量减1,标志着临界资源不可以再被访问了
3.如果访问完成了,则需要进行结束对临界资源的访问,对信号进行加1操作
减1操作:P操作
加1操作:V操作
怎么实现同步?---计数资源的个数
前提:信号量的值不在是0或者1了,信号量大于0的时候,表示有多少个资源可以使用。当信号量小于0的时候,小于0的数值的绝对值表示多少个进程在等待资源
1.如果需要访问该资源的时候,对信号量进行-1,访问资源
2.如果不访问该资源的时候,对信号量进行+1
3.如果当前信号量值是小于0,表示当前PCB等待队列当中还有进程在等待资源,当一个进程结束对该资源的访问的时候,应当唤醒PCB等待队列当中的一个进程,使之去获取资源
4.如果当前的信号量值大于0,表示PCB等待队列当中是没有进程在等待的,也就是不牵扯说需要唤醒没某个进程去获取资源
标签:大小 struct stat 个数 sigpipe fat 物理内存 怎么 虚拟内存
原文地址:https://blog.51cto.com/14233078/2468602