linux 共享内存--System V共享内存

1)用ftok()函数获得一个ID号.
应用说明:
在IPC中,我们经常用用key_t的值来创建或者打开信号量,共享内存和消息队列。这个在IPC的环境中十分的重要,比如说,服务器创建了一个消息队列,等待客户机发送请求。那么如何创建或者打开已有的消息队列呢?一般而言,我们对于服务器使用的路径和项目id(proj_id)是已知的,所以客户机可以获取相同的key来打开 消息队列并进行操作。
函数原型:
# include <sys/types.h>
# include <sys/ipc.h>


key_t ftok(const char *pathname, int proj_id);
Keys:
1)pathname一定要在系统中存在
2)pathname一定是使用进程能够访问的
3)proj_id是一个1-255之间的一个整数值,典型的值是一个ASCII值。
当成功执行的时候,一个key_t值将会被返回,否则-1被返回。我们可以使用errno来确定具体的错误信息如果我们很懒惰的话,不妨就使用perror函数来打印对应的出错字符信息。




2)shmget()用来开辟/指向一块共享内存的函数
应用说明:
shmget()用来获得共享内存区域的ID,如果不存在指定的共享区域就创建相应的区域。
函数原型:
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
key_t key 是这块共享内存的标识符。如果是父子关系的进程间通信的话,这个标识符用IPC_PRIVATE来代替。但是刚才我们的两个进程没有任何关系,所以就用ftok()算出来一个标识符使用了.总之可以有三种方法让程序指定关键字.一个是用IPC_PRIVATE,让系统产生一个关键字,挑选一个随机数.一个是自己指定,一个就是用ftok()函数.
int size 是这块内存的大小.
int flag 是这块内存的模式(mode)以及权限标识。
模式可取如下值:        新建:IPC_CREAT
                                   使用已开辟的内存:IPC_ALLOC
                                   如果标识符以存在,则返回错误值:IPC_EXCL
然后将“模式” 和“权限标识”进行“或”运算,做为第三个参数。
如:    IPC_CREAT | IPC_EXCL | 0666   (例子中的0666为权限标识)
这个函数成功时返回共享内存的ID,失败时返回-1。


 
3) shmat()将这个内存区映射到本进程的虚拟地址空间。
函数说明:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>


void    *shmat( int shmid , char *shmaddr , int shmflag );
shmat()是用来允许本进程访问一块共享内存的函数。
int shmid是那块共享内存的ID。
char *shmaddr是共享内存的起始地址
int shmflag是本进程对该内存的操作模式。如果是SHM_RDONLY的话,就是只读模式。其它的是读写模式
成功时,这个函数返回共享内存的起始地址。失败时返回-1。




4) shmdt()函数删除本进程对这块内存的使用
函数说明:
shmdt()与shmat()相反,是用来禁止本进程访问一块共享内存的函数。
函数原型:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmdt( char *shmaddr );
参数char *shmaddr是那块共享内存的起始地址。
成功时返回0。失败时返回-1。




5) shmctl() 控制对这块共享内存的使用
shmctl()函数说明:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int     shmctl( int shmid , int cmd , struct shmid_ds *buf );
int shmid是共享内存的ID。
int cmd是控制命令,可取值如下:
        IPC_STAT        得到共享内存的状态
        IPC_SET         改变共享内存的状态
        IPC_RMID        删除共享内存
struct shmid_ds *buf是一个结构体指针。IPC_STAT的时候,取得的状态放在这个结构体中。如果要改变共享内存的状态,用这个结构体指定。
返回值:        成功:0
                失败:-1
示例程序:
struct shmid_ds buf;
... ...
shmctl( shmid , IPC_STAT , &buf );      //      取得共享内存的状态
... ... 
shmctl( shmid , IPC_RMID , &buf );      //      删除共享内存
注意!!!:在使用共享内存,结束程序退出后。如果你没在程序中用shmctl()删除共享内存的话,一定要在命令行下用ipcrm命令删除这块共享内存。你要是不管的话,它就一直在那儿放着了。
简单解释一下ipcs命令和ipcrm命令。
取得ipc信息:
ipcs [-m|-q|-s]
-m      输出有关共享内存(shared memory)的信息
-q      输出有关信息队列(message queue)的信息
-s      输出有关“遮断器”(semaphore)的信息
%ipcs -m
删除ipc
ipcrm -m|-q|-s shm_id
%ipcrm -m 105
下面再介绍一下struct shmid_ds 的相关构成:
struct shmid_ds
-----------------------------------------------
    shmid_ds数据结构表示每个新建的共享内存。当shmget()创建了一块新的共享内存后,返回一个可以用于引用该共享内存的shmid_ds数据结构的标识符。
include/linux/shm.h
    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 */ 
    };


struct ipc_perm
-----------------------------------------------
    对于每个IPC对象,系统共用一个struct ipc_perm的数据结构来存放权限信息,以确定一个ipc操作是否可以访问该IPC对象。
    struct ipc_perm { 
        __kernel_key_t   key; 
        __kernel_uid_t   uid; 
        __kernel_gid_t   gid; 
        __kernel_uid_t   cuid; 
        __kernel_gid_t   cgid; 
        __kernel_mode_t mode; 
        unsigned short   seq; 
};
 
---------------------------------------------------------
修改文件及文件夹权限:


sudo chmod -(代表类型)×××(所有者)×××(组用户)×××(其他用户)


常用修改权限的命令:


sudo chmod 600 ××× (只有所有者有读和写的权限)


sudo chmod 644 ××× (所有者有读和写的权限,组用户只有读的权限)


sudo chmod 700 ××× (只有所有者有读和写以及执行的权限)


sudo chmod 666 ××× (每个人都有读和写的权限)


sudo chmod 777 ××× (每个人都有读和写以及执行的权限)

posted on 2013-11-16 21:15  lingzshen  阅读(236)  评论(0编辑  收藏  举报