共享内存

共享内存

注意:没有血缘关系的进程之间是可以通过文件进行通信的
只是文件描述符不一样,但是内核帮我们开辟的缓冲区是一个

复习

1、管道 环形队列 半双工 血缘关系进程间通信
2、FIFO 无血缘关系进程间通信 伪文件
管道的特点 数据读取之后 缓冲区就不再保留数据了
3、信号 异步通信机制
4、共享内存 效率最高
数据可反复读取

共享内存

可将磁盘上的东西映射到内存,那么就有地址了,好处就是可以使用指针操作了 。

缺点:容易发生进程的互斥,需要同步。
优点:通信效率高

共享内存使用步骤
1、创建共享内存 shmget()
2、将共享内存映射到自己的进程空间 shmat()
3、对共享内存进行读写
4、解除共享内存映射(shmdt())
5、删除共享内存(shmctl())
shmget()
        #include 
        #include 
        #include 

        int shmget(key_t key, int size, int shmflg);
        //通过同一个key可以得到同一块共享内存的ID

key的生成方式有三种


1、不同的进程约定好的一个值;
非0值表示,创建一个指定ID的共享内存
多个进程可以通过key值访问同一共享内存

2、通过相同的路径名和项目ID,调用ftok()函数,生成一个键;
    key_t ftok(const char *pathname, int proj_id);  
             创建IPC通讯时所必需的ID值。
            pathname:指定已经存在的文件名,一般是当前目录
          proj_id:子序列号,大小为1-255。

      返回值:ID值,大小是文件的索引节点号前加上子序列号,例如:pathname索引节点号为0x101010,proj_id为0x32,则ID为0x32101010。

3、还可以设置为IPC_PRIVATE(0),表示此共享内存是私有的,
      只能在父子进程之间使用

IPC_CREAT

成功,创建新对象

成功,引用已存在对象

IPC_CREAT|IPC_EXCL

成功,创建新对象

出错,errno=EEXIST

共享内存练习题
#include 
#include 
#include 
#include 
#include 
int main(int argc,char *argv[]){
        key_t key =  ftok("./", 0x70);
        int shmid = shmget(key,10*sizeof(int),IPC_CREAT|0666);//IPC_PRIVATE
        printf("shmid = %x\n",shmid);
        if(-1  == shmid){
            perror("shmget error!");
            exit(1);
        }
        pid_t pid  = fork();
        if(-1  == pid){
            perror("fork error!");
            exit(1);
        }else if(0 == pid){
            int *p = shmat(shmid, NULL,0);
            int i = 0;
            for(;i<10;i++){
                p[i]=i+1;
            }
            shmdt(p);
        //子进程
        }else{
        //父进程
            wait(NULL);
            int *p = shmat(shmid, NULL,0);
            int i = 0;
            for(;i<10;i++){
                //write(STDOUT_FILENO,p,sizeof(int)*10);
                printf("%3d",p[i]);
            }
            shmdt(p);
            shmctl(shmid,IPC_RMID, NULL);//删除共享内存
        }
}

注意: shmctl(shmid,IPC_RMID, NULL);//删除共享内存
千万别放在子进程中,否则直接就删除了。
ipcs -m 查看共享内存
ipcrm -m 134534 //删除共享内存 134534 shmid共享内存的ID

你可能感兴趣的:(共享内存)