Posted on 2008-02-19 11:30 
ZelluX 阅读(464) 
评论(0)  编辑  收藏  所属分类: 
Linux 、
System 
			 
			
		 
		《边干边学》上一个简单的共享内存的例程:


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

 #define KEY 1234
#define KEY 1234
 #define SIZE 1024
#define SIZE 1024

 int main()
int main()


 {
{
 int shmid;
    int shmid;
 char *shmaddr;
    char *shmaddr;
 struct shmid_ds buf;
    struct shmid_ds buf;

 shmid = shmget(KEY, SIZE, IPC_CREAT | 0600);
    shmid = shmget(KEY, SIZE, IPC_CREAT | 0600);

 if (shmid == -1)
    if (shmid == -1)  {
{
 printf("Failed in creating shared memory: %s\n", strerror(errno));
        printf("Failed in creating shared memory: %s\n", strerror(errno));
 return 0;
        return 0;
 }
    }


 if (fork() == 0)
    if (fork() == 0)  {
{
 shmaddr = (char *) shmat(shmid, NULL, 0);
        shmaddr = (char *) shmat(shmid, NULL, 0);


 if (shmaddr == (void *) -1)
        if (shmaddr == (void *) -1)  {
{
 printf("Failed in connecting to the shared memory: %s\n", strerror(errno));
            printf("Failed in connecting to the shared memory: %s\n", strerror(errno));
 return 0;
            return 0;
 }
        }
 
        
 strcpy(shmaddr, "Hello, this is child process!\n");
        strcpy(shmaddr, "Hello, this is child process!\n");
 shmdt(shmaddr);
        shmdt(shmaddr);
 return 0;
        return 0;

 } else
    } else  {
{
 sleep(3);
        sleep(3);
 shmctl(shmid, IPC_STAT, &buf);
        shmctl(shmid, IPC_STAT, &buf);
 
        
 printf("Size of the shared memory: ");
        printf("Size of the shared memory: ");
 printf("shm_segsz = %d bytes\n", buf.shm_segsz);
        printf("shm_segsz = %d bytes\n", buf.shm_segsz);
 printf("Process id of the creator: ");
        printf("Process id of the creator: ");
 printf("shm_cpid = %d\n", buf.shm_cpid);
        printf("shm_cpid = %d\n", buf.shm_cpid);
 printf("Process id of the last operator: ");
        printf("Process id of the last operator: ");
 printf("shm_lpid = %d\n", buf.shm_lpid);
        printf("shm_lpid = %d\n", buf.shm_lpid);

 shmaddr = (char *) shmat(shmid, NULL, 0);
        shmaddr = (char *) shmat(shmid, NULL, 0);


 if (shmaddr == (void *) -1)
        if (shmaddr == (void *) -1)  {
{
 printf("Failed in connecting the shared memory: %s\n", strerror(errno));
            printf("Failed in connecting the shared memory: %s\n", strerror(errno));
 return 0;
            return 0;
 }
        }

 printf("The content of the shared memory: %s\n", shmaddr);
        printf("The content of the shared memory: %s\n", shmaddr);

 shmdt(shmaddr);
        shmdt(shmaddr);
 shmctl(shmid, IPC_RMID, NULL);
        shmctl(shmid, IPC_RMID, NULL);
 }
    }
 }
}

主要的API:
shmget 创建一块共享内存
shmat 将一块已经存在的共享内存映射到一个进程的地址空间
shmdt 取消一个进程的地址空间中的一块共享块的映射
shmctl 管理共享内存,和ioctl的风格很像
每一个新创建的共享都由一个shmid_ds{}表示。struct shmid_ds在linux/shm.h中的定义:



 /**//* Obsolete, used only for backwards compatibility and libc5 compiles */
/**//* Obsolete, used only for backwards compatibility and libc5 compiles */

 struct shmid_ds
struct shmid_ds  {
{

 struct ipc_perm        shm_perm;    /**//* operation perms */
    struct ipc_perm        shm_perm;    /**//* operation perms */

 int            shm_segsz;    /**//* size of segment (bytes) */
    int            shm_segsz;    /**//* size of segment (bytes) */

 __kernel_time_t        shm_atime;    /**//* last attach time */
    __kernel_time_t        shm_atime;    /**//* last attach time */

 __kernel_time_t        shm_dtime;    /**//* last detach time */
    __kernel_time_t        shm_dtime;    /**//* last detach time */

 __kernel_time_t        shm_ctime;    /**//* last change time */
    __kernel_time_t        shm_ctime;    /**//* last change time */

 __kernel_ipc_pid_t    shm_cpid;    /**//* pid of creator */
    __kernel_ipc_pid_t    shm_cpid;    /**//* pid of creator */

 __kernel_ipc_pid_t    shm_lpid;    /**//* pid of last operator */
    __kernel_ipc_pid_t    shm_lpid;    /**//* pid of last operator */

 unsigned short        shm_nattch;    /**//* no. of current attaches */
    unsigned short        shm_nattch;    /**//* no. of current attaches */

 unsigned short         shm_unused;    /**//* compatibility */
    unsigned short         shm_unused;    /**//* compatibility */

 void             *shm_unused2;    /**//* ditto - used by DIPC */
    void             *shm_unused2;    /**//* ditto - used by DIPC */

 void            *shm_unused3;    /**//* unused */
    void            *shm_unused3;    /**//* unused */
 };
};其中存放权限信息的ipc_perm{}的定义为:
include/linux/ipc.h



 /**//* Obsolete, used only for backwards compatibility and libc5 compiles */
/**//* Obsolete, used only for backwards compatibility and libc5 compiles */
 struct ipc_perm
struct ipc_perm


 {
{
 __kernel_key_t    key;
    __kernel_key_t    key;
 __kernel_uid_t    uid;
    __kernel_uid_t    uid;
 __kernel_gid_t    gid;
    __kernel_gid_t    gid;
 __kernel_uid_t    cuid;
    __kernel_uid_t    cuid;
 __kernel_gid_t    cgid;
    __kernel_gid_t    cgid;
 __kernel_mode_t    mode;
    __kernel_mode_t    mode; 
 unsigned short    seq;
    unsigned short    seq;
 };
};mode为该共享的内存的读写权限,和chmod的参数有点像。mode低九位定义了访问许可,解释如下:
0400 用户可读  0200用户可写  0040 组成员可读  0020 组成员可写  0004 其他用户可读  0002 其他用户可写
没有执行位 0100 0010 和 0001