Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15342164
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2009-07-11 11:14:47

对于系统中共享信号或者共享内存的创建和删除可以使用ipcs命令,独立完成.
luther@gliethttp:~$ ipcs -sm 查询
luther@gliethttp:~$ ipcs -h 获得帮助

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

struct lcd_info {
    int width; // 屏宽
    int height; // 屏高
    int depth; // 每点像素数
    int line_bytes; // 每行字节数
    int data_offset;// 数据区开始偏移值
};

int shmId;

int main(void)
{
    int data_size;
    void *data;
    struct lcd_info lcd;
    struct shmid_ds shm;

    key_t key = ftok("/sbin/init", 'g');
    // 根据init文件的ino节点号,dev设备号,和id组合出一个key序列串,作为唯一key标识[luthr.gliethttp]
    // ftok库实现为
    // key_t ftok(const char* path, int id)
    // {
    // struct stat st;
    // if ( lstat(path, &st) < 0 )
    // return -1;
    // return (key_t)( (st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16) | ((id & 255) << 24) );
    // }
   
    lcd.width = 800;
    lcd.height = 600;
    lcd.depth = 16;
    lcd.line_bytes = lcd.width * ((lcd.depth+7) >> 3);
    lcd.data_offset = 512;
    data_size = lcd.line_bytes*lcd.height + lcd.data_offset; // 0-511字节存放控制信息[luther.gliethttp]
    // 跳过前512字节的控制信息空间[luther.gliethttp]

    shmId = shmget( key, data_size, IPC_CREAT|0666); // 创建一个data_size大小的共享内存,该共享内存
    // 对应的唯一索引值为key,调用shmget(key, 0, 0);可以获得该共享内存[luther.gliethttp]
    if ( shmId != -1 )
        data = (unsigned char *)shmat( shmId, 0, 0 );
    else {
        shmctl( shmId, IPC_RMID, &shm ); // 删除已经存在的key相同的共享内存[luther.gliethttp].
        shmId = shmget( key, data_size, IPC_CREAT|0666);
        data = (unsigned char *)shmat( shmId, 0, 0 );
    }

    if ((int)data == -1) {
        printf("Error : shmget\n");
        return -1;
    }
    
    *((struct lcd_info*)data) = lcd;

    for (;;) {
        sleep(1);
    }

    shmctl( shmId, IPC_RMID, &shm ); // 删除共享内存,当然这里是不会执行到这了,应该在signal回调函数中执行,不过再次启动的时候,会自动删除[luther.gliethttp].
    return 0;
}

luther@gliethttp:/vobs/tmp$ gcc -o server shmget.c
luther@gliethttp:/vobs/tmp$ ./server

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

struct lcd_info {
    int width; // 屏宽
    int height; // 屏高
    int depth; // 每点像素数
    int line_bytes; // 每行字节数
    int data_offset;// 数据区开始偏移值
};

int shmId;

int main(void)
{
    struct lcd_info *lcd;

    key_t key = ftok("/sbin/init", 'g');
    // 根据init文件的ino节点号,dev设备号,和id组合出一个key序列串,作为唯一key标识[luthr.gliethttp]
    // ftok库实现为
    // key_t ftok(const char* path, int id)
    // {
    // struct stat st;
    // if ( lstat(path, &st) < 0 )
    // return -1;
    // return (key_t)( (st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16) | ((id & 255) << 24) );
    // }

    shmId = shmget(key, 0, 0);
    if (shmId != -1)
        lcd = shmat(shmId, 0, 0);
    else {
        printf("[luther.gliethttp] shmId=-1\n");
        return -1;
    }
    
    printf("=====[luther.gliethttp.lcd.info]=====\n"
           "width\t\t= %d\n"
           "height\t\t= %d\n"
           "depth\t\t= %d\n"
           "line_bytes\t= %d\n"
           "data_offset\t= %d\n",
           lcd->width,
           lcd->height,
           lcd->depth,
           lcd->line_bytes,
           (unsigned int)lcd->data_offset);
    return 0;
}

luther@gliethttp:/vobs/tmp$ gcc -o client shmget2.c
luther@gliethttp:/vobs/tmp$ ./client
=====[luther.gliethttp.lcd.info]=====
width        = 800
height        = 600
depth        = 16
line_bytes    = 1600
data_offset    = 512
luther@gliethttp:/vobs/tmp$
阅读(3643) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~