IPC之共享内存

原创
2012/06/29 22:23
阅读数 1.3K

       共享内存作为IPC(Inter-Process Communication)的一种方式,适合同一台机器上不同进程间的相互通信,由于不同进程直接对同一块"约定好"的内存进行操作,因此效率为所有IPC中最高的。

    共享内存的使用还是很简单的,主要涉及到五个函数的使用,下面一一进行介绍。

     (1)key_t ftok(const char *pathname, int proj_id);

                功能:用来创建System V IPC的一个key值

                参数:pathname:系统中真实存在的并可以访问的目录或文件

                          proj_id   :在1~255之间的数值,可以用来标识这是该进程创建的第几块共享内存

              返回值:成功则返回一个key_t值;失败返回-1.

     (2)int shmget(key_t key, size_t size, int shmflg);

                功能:用来创建一块共享内存

                参数:  key    :由ftok返回的值

                           size    :需要创建共享内存的大小

                           shmflg:共享内存的模式及权限标识

                                     模式可以取如下值:

                                     IPC_CREAT: 新建一块共享内存

                                     IPC_ALLOC: 使用已开辟的内存

                                     IPC_EXCL   : 如果标识符已存在,则返回错误值      

               返回值:成功则返回一个标志值;失败返回-1.

        (3)void *shmat(int shmid, const void *shmaddr, int shmflg);

                功能:把由shmid标识的共享内存attach到该进程的地址空间

                参数: shmid     :由shmget返回的共享内存的标志

                           shmaddr :把共享内存attach在进程地址空间的起始地址,一般设为0

                            shmflg   :进程对该内存的操作模式。SHM_RDONLY表示只读模式,其它为读写模式。

              返回值:成功则返回一个共享内存起始地址;失败返回(void *)-1.

       (4)int shmdt(const void *shmaddr);

                功能:删除一块共享内存

                参数: shmaddr :要从进程中detach的共享内存地址

              返回值:成功则返回0;失败返回-1.

       (5) int shmctl(int shmid, int cmd, struct shmid_ds *buf);

                功能:执行对共享内存的控制

                参数:  shmid :标志共享内存的id

                            cmd    :控制命令,可取值如下:

                                        IPC_STAT  :得到共享内存的状态
                                        IPC_SET    :改变共享内存的状态
                                        IPC_RMID  :删除共享内存

                             buf    :用来存放共享内存的状态

              返回值:失败返回-1;成功返回其他值。

      下面看两个使用共享内存通信进程的例子:

//process1.cc

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/ipc.h>

#define MAX_SHM_SIZE 1024*1024

int main(int argc, char *argv[])
{
    const char *name = "/home/pathenon/project/network";
    int i = 1;

    key_t key = ftok(name, i);
    if(-1 == key)
    {
        perror("ftok");
        return 1;
    }

    int shm_id=shmget(key, MAX_SHM_SIZE, IPC_CREAT|0666);
    if(-1 == shm_id)
    {
        perror("shmget");
        return 1;
    }

    char buffer[] = "Hello share memory ipc\n";
    char *p = (char *)shmat(shm_id, 0, 0);
    if((void *)-1 == (void *)p)
    {
        perror("shmat");
        return 1;
    }

    //write memory
    int size = sizeof(buffer);
    memcpy(p, &size, 4);
    memcpy(p+4, buffer, sizeof(buffer));

    shmdt(p);

    return 0;
}

//process2.cc

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/ipc.h>

#define MAX_SHM_SIZE 1024*1024

int main()
{
    const char *name = "/home/pathenon/project/network";
    int i = 1;

    key_t key = ftok(name, i);
    if(-1 == key)
    {
        perror("ftok");
        return 1;
    }

    int shm_id=shmget(key, MAX_SHM_SIZE, IPC_CREAT|0666);
    if(-1 == shm_id)
    {
        perror("shmget");
        return 1;
    }

    char *p = (char *)shmat(shm_id, 0, 0);
    if((void *)-1 == (void *)p)
    {
        perror("shmat");
        return 1;
    }

    //read memory
    int size;
    memcpy(&size, p, 4);
    char buffer[1024] = {'\0'};
    memcpy(buffer, p+4, size);

    printf("%s", buffer);

    shmdt(p);

    return 0;
}

   分别编译上面两个程序,并先运行第一个可执行程序,后运行第二个,会发现输出:Hello share memory ipc     

   我们可以总结一下使用共享内存的大致步骤:

    1.使用ftok获得一个key_t值

    2.使用 shmget()开辟一块共享内存

    3.使用shmat()允许本进程使用某块共享内存

  4.对共享内存进行操作
  5.禁止本进程使用这块共享内存 shmdt()

    6.使用shmctl()或者命令行下ipcrm删除这块共享内存

     注意:在使用完共享内存后,如果没有在程序中用shmctl()删除共享内存就退出程序,一定要在命令行下用ipcrm命令删除这块共享内存否则它就一直在那儿放着。

     下面使用ipcs命令和ipcrm命令来查看与删除共享内存。

>ipcs -m

------ Shared Memory Segments --------

key        shmid      owner      perms      bytes      nattch     status

0x00000000 65538      yangfan    600        196608     2         

>ipcrm -m 65538

------ Shared Memory Segments --------

key        shmid      owner      perms      bytes      nattch     status

0x00000000 65538      yangfan    600        196608     2          dest

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
2 收藏
1
分享
返回顶部
顶部