0
点赞
收藏
分享

微信扫一扫

Linux——进程和计划任务管理

caoxingyu 2023-05-28 阅读 110

1 共享内存示意图

 


2 共享内存数据结构

struct shmid_ds {
 struct ipc_perm shm_perm; /* operation perms */
 int shm_segsz; /* size of segment (bytes) */
 __kernel_time_t shm_atime; /* last attach time */
 __kernel_time_t shm_dtime; /* last detach time */
 __kernel_time_t shm_ctime; /* last change time */
 __kernel_ipc_pid_t shm_cpid; /* pid of creator */
 __kernel_ipc_pid_t shm_lpid; /* pid of last operator */
 unsigned short shm_nattch; /* no. of current attaches */
 unsigned short shm_unused; /* compatibility */
 void *shm_unused2; /* ditto - used by DIPC */
 void *shm_unused3; /* unused */
};

3 共享内存函数(重点)

  • shmget函数:

 shmflg一般常用的权限位有两个:IPC_CREAT and IPC_EXCL

 我们如何获得该函数的第一个参数key呢?

我们可以使用ftok函数:

用返回值接受到生成的key_t类型即可。

  • shmat函数:

说明:

  • shmdt函数 :

  •  shmctl函数:

 


4 用共享内存实现一个客户端与服务端通信的案例

comm.hpp:

#include<iostream>
#include<cerrno>
#include<cstring>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/stat.h>
#include<unistd.h>
using namespace std;

#define PATHNAME "."
#define PROJID 6666
key_t getKey()
{
    key_t key=ftok(PATHNAME,PROJID);
    if(key==-1)
    {
        cout<<"error"<<errno<<":"<<strerror(errno)<<endl;
        return 1;
    }
    return key;
}

int creatShm(size_t size,int shmflag=0)
{
    umask(0);
    int shmid=shmget(getKey(),size,IPC_CREAT | IPC_EXCL | 0666);
    if(shmid==-1)
    {
        cout<<"error"<<errno<<":"<<strerror(errno)<<endl;
        return 1;
    }
    return shmid;
}


int getShm(size_t size,int shmflag=0)
{
    int shmid=shmget(getKey(),size,IPC_CREAT );
    if(shmid==-1)
    {
        cout<<"error"<<errno<<":"<<strerror(errno)<<endl;
        return 1;
    }
    return shmid;
}


char* attachShm(int shmid)
{
    char* start=(char*)shmat(shmid,nullptr,0);
    return start;
}

void detouchShm(char* start)
{
    int n=shmdt(start);
    if(n==-1)
    {
        cout<<"error"<<errno<<":"<<strerror(errno)<<endl;
        return ;
    }
}

void delShm(int shmid)
{
    int n=shmctl(shmid,IPC_RMID,nullptr);
    if(n==-1)
    {
        cout<<"error"<<errno<<":"<<strerror(errno)<<endl;
        return ;
    }
}

server.cc:

#include<iostream>
#include"comm.hpp"


int main()
{
    //1 创建共享内存
    int shmid=creatShm(4096);

    //2 将共享内存与自己关联起来
    char* start=attachShm(shmid);

    //3 使用共享内存通信
    int cnt=0;
    while(cnt<=15)
    {
        cout<<start<<endl;
        sleep(1);
        ++cnt;
    }

    //4 解除自己与共享内存的关联
    detouchShm(start);

    //5 删除共享内存
    delShm(shmid);
    return 0;
}

client.cc:

#include<iostream>
#include"comm.hpp"


int main()
{
    //1 创建共享内存
    int shmid=getShm(4096);

    //2 将共享内存与自己关联起来
    char* start=attachShm(shmid);

    //3 使用共享内存通信
    char ch='A';
    while(ch<='Z')
    {
        start[ch-'A']=ch;
        ++ch;
        start[ch-'A']=0;
        sleep(1);
    }    
    //4 解除自己与共享内存的关联
    detouchShm(start);

    //客户端不要删掉共享内存
    return 0;
}

这样我们便能够正常运行我们的程序了,但是假如我们不小心终止了./server进程而导致共享内存没有被删除,我们可以用命令行来删除共享内存。

查看共享内存命令:

ipcs -m

删除指定共享内存:

ipcrm -m 共享内存的id
举报

相关推荐

0 条评论