c 语言 共享内存,[C语言]进程间通信——共享内存 - 代码贴 - BCCN

*******************************************************************************

进程间通信方式之一: 共享内存

进程1:创建共享内存1和共享内存2,并初始化共享内存1为0,并输出初始化之后的共享内存1的内容,然后重新给共享内存1赋予新的内容并输出该内容;与此同时给共享内存2赋予一定的内容并输出,之后再sleep 60秒,删除共享内存1和共享内存2。

进程2:在进程1运行的时候(进程1在sleep 60秒的时候),连接共享内存1和共享内存2并输出共享内存里面的内容。

运行结果:运行环境 Linux

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~终端1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[root@localhost shm]# gcc -g strlen1.c -o strlen1 //编译

[root@localhost shm]# gcc -g strlen2.c -o strlen2

[root@localhost shm]# ./strlen1 //运行进程1

***************************************

shmget1 ok. //创建共享内存1

shmat1 ok.

shmget2 ok. //创建共享内存2

shmat2 ok.

***************************************

~~~~~~~~~~~~~~~Result0~~~~~~~~~~~~~~~~~

The 1th before shm1 info is : //初始化共享内存1 输出的初始化之后的内容

00000000

00000000

~~~~~~~~~~~~~~~Result0~~~~~~~~~~~~~~~~~

=======================================

Please input two long number : //给共享内存1中输入新的内容

255

65535

a[0]=ff,a[1]=ffff,a[0]=255,a[1]=65535 //分别为十六进制输出和十进制输出

Please input a string and lenth<24 :

//给共享内存2中输入新的内容,注意共享内存2并没有初始化。

wo ai ni ma

=======================================

~~~~~~~~~~~~~~~Result0~~~~~~~~~~~~~~~~~

The 2th after shm1 info is :

ff000000

ffff0000

The shm2 info is :

wo ai ni ma

~~~~~~~~~~~~~~~Result0~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~Result1~~~~~~~~~~~~~~~~~

The 1th before shm1 info is :

00000000

00000000

~~~~~~~~~~~~~~~Result1~~~~~~~~~~~~~~~~~

=======================================

Please input two long number :

888888

65535

a[0]=d9038,a[1]=ffff,a[0]=888888,a[1]=65535

Please input a string and lenth<24 :

ke xiao

=======================================

~~~~~~~~~~~~~~~Result1~~~~~~~~~~~~~~~~~

The 2th after shm1 info is :

38900d00

ffff0000

The shm2 info is :

ke xiao

~~~~~~~~~~~~~~~Result1~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~Result2~~~~~~~~~~~~~~~~~

The 1th before shm1 info is :

00000000

00000000

~~~~~~~~~~~~~~~Result2~~~~~~~~~~~~~~~~~

=======================================

Please input two long number :

12345678

111111

a[0]=bc614e,a[1]=1b207,a[0]=12345678,a[1]=111111

Please input a string and lenth<24 :

fang huo xiang

=======================================

~~~~~~~~~~~~~~~Result2~~~~~~~~~~~~~~~~~

The 2th after shm1 info is :

4e61bc00

07b20100

The shm2 info is :

fang huo xiang

~~~~~~~~~~~~~~~Result2~~~~~~~~~~~~~~~~~

***************************************

shm1 shmdt ok. //断开与共享内存1的连接

shmctl1 ok. //删除共享内存1

shm2 shmdt ok.

shmctl2 ok.

***************************************

[root@localhost shm]#

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~终端2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[root@localhost shm]# ./strlen2 //在终端1 sleep 60秒的时候,在终端2运行进程2

**************************************

shmget1 ok.

shmat1 ok. //连接共享内存

shmget2 ok

shmat2 ok.

**************************************

~~~~~~~~~~~~~~~~~~Result0~~~~~~~~~~~~~ //每隔10秒输出一次共享内存的内容

shm1 info is : //当前共享内存1的内容

00000000

00000000

shm2 info is : //当前共享内存2里面美誉内容

~~~~~~~~~~~~~~~~~~Result0~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~Result1~~~~~~~~~~~~~

shm1 info is : //当前共享内存1中的内容发生了变化

ff000000

ffff0000

shm2 info is :

~~~~~~~~~~~~~~~~~~Result1~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~Result2~~~~~~~~~~~~~

shm1 info is :

ff000000

ffff0000

shm2 info is :

wo ai ni ma

~~~~~~~~~~~~~~~~~~Result2~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~Result3~~~~~~~~~~~~~

shm1 info is :

00000000

00000000

shm2 info is :

wo ai ni ma

~~~~~~~~~~~~~~~~~~Result3~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~Result4~~~~~~~~~~~~~

shm1 info is :

38900d00

ffff0000

shm2 info is :

ke xiao

~~~~~~~~~~~~~~~~~~Result4~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~Result5~~~~~~~~~~~~~

shm1 info is :

00000000

00000000

shm2 info is :

ke xiao

~~~~~~~~~~~~~~~~~~Result5~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~Result6~~~~~~~~~~~~~

shm1 info is :

00000000

00000000

shm2 info is :

ke xiao

~~~~~~~~~~~~~~~~~~Result6~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~Result7~~~~~~~~~~~~~

shm1 info is :

4e61bc00

07b20100

shm2 info is :

fang huo xiang

~~~~~~~~~~~~~~~~~~Result7~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~Result8~~~~~~~~~~~~~

shm1 info is :

4e61bc00

07b20100

shm2 info is :

fang huo xiang

~~~~~~~~~~~~~~~~~~Result8~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~Result9~~~~~~~~~~~~~

shm1 info is :

4e61bc00

07b20100

shm2 info is :

fang huo xiang

~~~~~~~~~~~~~~~~~~Result9~~~~~~~~~~~~~

**************************************

shm1 shmdt ok.

shm2 shmdt ok.

**************************************

[root@localhost shm]#

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

改进:

在进程1中每隔10秒重新给共享内存1、共享内存2填充新的内容并输出,不断运行

进程2(每十秒中输出共享内存1和共享内存2中的内容),查看内存内容是否同步。

另外,有可能发生进程1正在给共享内存1填充内容,与此同时进程2正好访问共享内存1,结果是什么样的,怎样修改需要实验。

可以考虑信号量,互斥量。

注意:

在进程1即将结束的时候,运行进程2,当进程1结束后,共享内存1和共享内存2已经被

进程1删除了,但是连接到进程2的共享内存1和共享内存2,并没有断开连接,进程2会一直输出最后保存在共享内存里面的内容(映射到该进程2空间的共享内存)

*******************************************************************************

进程1

#include

#include

#include

#include

#include

#include

#include

#include

int main(){

char *shmaddr1=NULL;

int *shmaddr2=NULL;

int shmid1;

int shmid2;

int ret;

long a[2];

unsigned char *blk_tp=NULL;

int i=0;

char str[24];

int count=0; //可以注释掉

printf("***************************************\n");

shmid1 = shmget((key_t)123,24,IPC_CREAT|IPC_EXCL);

//创建共享内存1,24个字节

if(-1 == shmid1){

printf("shmget1error.\n");

return -1;

}else{

printf("shmget1ok.\n");

}

shmaddr1 = shmat(shmid1,0,SHM_RND); //将该共享内存1映射到该进程空间

if(-1 == (long)shmaddr1){

printf("shmat1error.\n");

return -1;

}else{

printf("shmat1ok.\n");

}

shmid2 = shmget((key_t)234,24,IPC_CREAT|IPC_EXCL); //创建共享内存2

if(-1 == shmid2){

printf("shmget2error.\n");

return -1;

}else{

printf("shmget2ok.\n");

}

shmaddr2 = shmat(shmid2,0,SHM_RND); //将共享内存2映射到该进程空间

if(-1 == (long)shmaddr2){

printf("shmat2error.\n");

return -1;

}else{

printf("shmat2ok.\n");

}

printf("***************************************\n");

printf("\n");

while(count<3) //这个循环输入可以注释掉,仅仅一次就可以验证共享内存是同步的

{ //这个可以注释掉

printf("~~~~~~~~~~~~~~~Result%d~~~~~~~~~~~~~~~~~\n",count);

// printf("sizeof(shmaddr1) is %d \n",sizeof(shmaddr1));

//此次输出仅仅是shmaddr1指针的大小

memset(shmaddr1,0x00,sizeof(a)); //将该共享内存1初始化为0

blk_tp=(unsigned char*)shmaddr1;

i=2*sizeof(long);

printf("The 1th before shm1 info is :\n");

while(i>=4){ //初始化之后,输出该共享内存的内容,每四个字节输出一次

printf("%02x%02x%02x%02x\n",*blk_tp,*(blk_tp+1),*(blk_tp+2),*(blk_tp+3));

blk_tp+=4;

i -= 4;

}

printf("~~~~~~~~~~~~~~~Result%d~~~~~~~~~~~~~~~~~\n",count);

printf("\n");

sleep(4);

memset(a,0,sizeof(a)); //初始化数组a

// printf("sizeof(long) is %d, sizeof(a) is %d. \n",sizeof(long),sizeof(a));

printf("=======================================\n");

printf("Please input two long number :\n");

scanf("%ld %ld",&a[0],&a[1]); //初始化数组a 一个long是4个字节

getchar();

printf("a[0]=%0x,a[1]=%0x,a[0]=%ld,a[1]=%ld\n",a[0],a[1],a[0],a[1]);

memmove(shmaddr1,a,sizeof(a)); //将共享内存1的内容设置为a数组里面的内容

// printf("strlen(shmaddr1) is %d. \n",strlen((char *)shmaddr1));

printf("Please input a string and lenth<24 :\n");

gets(str); //给共享内存2重新填充新的内容

memmove(shmaddr2,str,24);

printf("=======================================\n");

// printf("strlen(shmaddr2) is %d. \n",strlen((char *)shmaddr2));//求该共享内存的大小

blk_tp=(unsigned char*)shmaddr1;

i=2*sizeof(long);

printf("\n");

printf("~~~~~~~~~~~~~~~Result%d~~~~~~~~~~~~~~~~~\n",count);

printf("The 2th after shm1 info is :\n");

while(i>=4){ //重新输出共享内存1的内容

printf("%02x%02x%02x%02x\n",*blk_tp,*(blk_tp+1),*(blk_tp+2),*(blk_tp+3));

blk_tp+=4;

i -= 4;

}

printf("The shm2 info is :\n%s\n",shmaddr2); //输出共享内存2的内容

printf("~~~~~~~~~~~~~~~Result%d~~~~~~~~~~~~~~~~~\n",count);

count++;

sleep(10);

//sleep 10秒,等待验证进程间数据共享,先运行strlen1,之后再运行strlen2,验证进程间数//据共享

}//这个可以注释掉

sleep(20);

printf("\n");

printf("***************************************\n");

ret = shmdt(shmaddr1); //该进程和共享内存1,断开连接

if(-1 == ret)

{

printf(" shm1 shmdt errno.\n");

}else{

printf(" shm1 shmdt ok.\n");

}

ret = shmctl(shmid1,IPC_RMID,0); //删除共享内存1

if(-1 == ret){

printf("shmctl1errno.\n");

}else{

printf("shmctl1ok.\n");

}

ret = shmdt(shmaddr2); //该进程和共享内存2,断开连接

if(-1 == ret)

{

printf(" shm2 shmdt errno.\n");

}else{

printf(" shm2 shmdt ok.\n");

}

ret = shmctl(shmid2,IPC_RMID,0); //删除共享内存2

if(-1 == ret){

printf("shmctl2errno.\n");

}else{

printf("shmctl2ok.\n");

}

printf("***************************************\n");

return 0;

}

进程2

#include

#include

#include

#include

#include

#include

#include

#include

int main(){

char *shmaddr1=NULL;

int *shmaddr2=NULL;

int shmid1;

int shmid2;

int ret;

int i=0;

unsigned char *blk_tp=NULL;

long a[2];

int count=0; //这个可以注释掉

printf("**************************************\n");

shmid1 = shmget((key_t)123,0,0); //连接共享内存1

if(-1 == shmid1){

printf("shmget1error.\n");

return -1;

}else{

printf("shmget1ok.\n");

}

shmaddr1 = shmat(shmid1,0,SHM_RND); //将共享内存1映射到该进程空间

if(-1 == (long)shmaddr1){

printf("shmat1error.\n");

return -1;

}else{

printf("shmat1ok.\n");

}

shmid2 = shmget((key_t)234,0,0); //连接共享内存2

if(-1 == shmid2){

printf("shmget2error.\n");

return -1;

}else{

printf("shmget2ok\n");

}

shmaddr2 = shmat(shmid2,0,SHM_RND); //将共享内存2映射到该进程空间

if(-1 == (long)shmaddr2){

printf("shmat2error.\n");

return -1;

}else{

printf("shmat2ok.\n");

}

printf("**************************************\n");

printf("\n");

while(count<10) //这个可以注释掉

{ //可以注释掉

printf("~~~~~~~~~~~~~~~~~~Result%d~~~~~~~~~~~~~\n",count);

// printf("strlen(shmaddr1) is %d. \n",strlen(shmaddr1)); //求共享内存1的大小

blk_tp=(unsigned char*)shmaddr1;

i=2*sizeof(long);

printf("shm1 info is :\n");

while(i>=4){ //输出该共享内存1的内容

printf("%02x%02x%02x%02x\n",*blk_tp,*(blk_tp+1),*(blk_tp+2),*(blk_tp+3));

blk_tp+=4;

i -= 4;

}

// printf("strlen(shmaddr2) is %d. \n",strlen((char *)shmaddr2));

//求共享内存2的大小

printf("shm2 info is :\n%s\n",shmaddr2); //输出共享内存2的内容

printf("~~~~~~~~~~~~~~~~~~Result%d~~~~~~~~~~~~~\n",count);

count++;

sleep(10);

} //可以注释掉

printf("\n");

printf("*****************************************\n");

ret = shmdt(shmaddr1); //该进程和共享内存1,断开连接

if(-1 == ret)

{

printf(" shm1 shmdt errno.\n");

}else{

printf(" shm1 shmdt ok.\n");

}

ret = shmdt(shmaddr2); //该进程和共享内存2,断开连接

if(-1 == ret)

{

printf(" shm2 shmdt errno.\n");

}else{

printf(" shm2 shmdt ok.\n");

}

printf("*****************************************\n");

return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值