进程间通信:共享内存Shmem.c分析
2016-01-21 09:27
806 查看
Shmem分析
源代码加注释:
点击(此处)折叠或打开
#include <stdlib.h>
//exit()
#include <stdio.h>
//printf()
#include <string.h>
//memset()
#include <errno.h>
//errno
#include <unistd.h>
//sleep()
#include <sys/stat.h>
// S_IRUSR|S_IWUSR
#include <sys/types.h>
//不知道什么用
#include <sys/ipc.h>
//不知道什么用
#include <sys/shm.h>
//shmget() shmat()
#define PERM S_IRUSR|S_IWUSR
// PERM <===> S_IRUSR|S_IWUSR
/* 共享内存
*/
int main(int argc,char
**argv)
//char
**argv:指向指针的指针 《C书》P271(下:详)
{
int shmid;
//共享内存ID
char *p_addr,*c_addr;
//初始化 内存实际地址(《UNIX书》上这么说的)
if(argc!=2)
//判断入参
{
fprintf(stderr,"Usage:%s\n\a",argv[0]);
//入参不是2就打印出使用方法
exit(1);
}
/* 创建共享内存
*/
if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1)
{
fprintf(stderr,"Create Share Memory Error:%s\n\a",strerror(errno));//创建共享内存失败信息
exit(1);
}
/* 创建子进程
*/
if(fork())
// 父进程写
//fork()返回值:子进程返回0,父进程中返回子ID
{ //子进程ID不可能为负 这样写更容易理解:
//
if(fork()>0)
p_addr=shmat(shmid,0,0);
//共享内存的第二步:映射共享内存
memset(p_addr,'\0',1024);
//格式化内存(下详解)
strncpy(p_addr,argv[1],1024);
//写入数据(下详解)
wait(NULL);
// 释放资源,不关心终止状态(父停让子运行,等待子运行完毕)
exit(0);
}
else // 子进程读 ( ”else” 也可以用 ”if(fork()=0)”
)
{
sleep(1);
// 暂停1秒
(假若子先运行了,自觉停让父运行到wai())
c_addr=shmat(shmid,0,0);
//这时候共享内存中已有数据,子映射共享内存
printf("Client get %s\n",c_addr);
//打印出映射出的内容,
exit(0);
}
}
char **argv:(以下是谭老师原文)
memset(p_addr,'\0',1024):
将p_addr中1024个字节替换为“\0”,并返回p_addr(本函数没有取其返回值,因为没有发生变化)
strncpy(p_addr,argv[1],1024):
把argv[1]处最多1024个字符复制到字符数组的p_addr中,返回指向p_addr的指针。(本函数也没有取其返回值,因为不需要,只要共享内存中有数据即可)
运行结果:
源代码加注释:
点击(此处)折叠或打开
#include <stdlib.h>
//exit()
#include <stdio.h>
//printf()
#include <string.h>
//memset()
#include <errno.h>
//errno
#include <unistd.h>
//sleep()
#include <sys/stat.h>
// S_IRUSR|S_IWUSR
#include <sys/types.h>
//不知道什么用
#include <sys/ipc.h>
//不知道什么用
#include <sys/shm.h>
//shmget() shmat()
#define PERM S_IRUSR|S_IWUSR
// PERM <===> S_IRUSR|S_IWUSR
/* 共享内存
*/
int main(int argc,char
**argv)
//char
**argv:指向指针的指针 《C书》P271(下:详)
{
int shmid;
//共享内存ID
char *p_addr,*c_addr;
//初始化 内存实际地址(《UNIX书》上这么说的)
if(argc!=2)
//判断入参
{
fprintf(stderr,"Usage:%s\n\a",argv[0]);
//入参不是2就打印出使用方法
exit(1);
}
/* 创建共享内存
*/
if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1)
{
fprintf(stderr,"Create Share Memory Error:%s\n\a",strerror(errno));//创建共享内存失败信息
exit(1);
}
/* 创建子进程
*/
if(fork())
// 父进程写
//fork()返回值:子进程返回0,父进程中返回子ID
{ //子进程ID不可能为负 这样写更容易理解:
//
if(fork()>0)
p_addr=shmat(shmid,0,0);
//共享内存的第二步:映射共享内存
memset(p_addr,'\0',1024);
//格式化内存(下详解)
strncpy(p_addr,argv[1],1024);
//写入数据(下详解)
wait(NULL);
// 释放资源,不关心终止状态(父停让子运行,等待子运行完毕)
exit(0);
}
else // 子进程读 ( ”else” 也可以用 ”if(fork()=0)”
)
{
sleep(1);
// 暂停1秒
(假若子先运行了,自觉停让父运行到wai())
c_addr=shmat(shmid,0,0);
//这时候共享内存中已有数据,子映射共享内存
printf("Client get %s\n",c_addr);
//打印出映射出的内容,
exit(0);
}
}
char **argv:(以下是谭老师原文)
memset(p_addr,'\0',1024):
将p_addr中1024个字节替换为“\0”,并返回p_addr(本函数没有取其返回值,因为没有发生变化)
strncpy(p_addr,argv[1],1024):
把argv[1]处最多1024个字符复制到字符数组的p_addr中,返回指向p_addr的指针。(本函数也没有取其返回值,因为不需要,只要共享内存中有数据即可)
运行结果:
相关文章推荐
- LWIP UDP 协议分析
- 如何减小与“大牛”的差距
- 图的遍历
- 面试中经常碰到的C语言算法
- MPlayer播放器源码分析
- 精·彩 没我怎么型! LG L3新款手机中国发布
- (转帖)Ascii码表(全)
- Linux独立中断栈学习笔记及验证实验(ARM、x86)
- 16道嵌入式C语言面试题(经典)
- gradle maven私服构建aar
- HQL: Hibernate查询语言
- 使用Eclipse开发Android报错:Project has no target set. Edit the project properties to set one.
- Hibernate 一对多级联删除
- [转] 高效的产生一组不重复的随机数
- TCP/UDP相关知识总汇
- shell外部命令解析器
- u-boot启动完全分析
- 算法导论(八)--线性时间排序
- linux 多点触控协议
- 这样学习C语言最有效