博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
共享内存linux C/C++代码实战------顺便玩下ipcs, ipcrm, shmget, shmat, shmdt, shmctl
阅读量:4142 次
发布时间:2019-05-25

本文共 4069 字,大约阅读时间需要 13 分钟。

       在学校的时候, 谁会搞共享内存这些东西呢? 不过是为了笔试和面试, 大家才搞一下吧。 但是, 在实际工作中, 共享内存确实应用较广。

       其实, 共享内存的思想很简单, 我来举个俗气的例子, writer进程和和reader进程通信, 最简单的方式是什么: 当然是共享文件啊。 writer进程把数据写到a.txt文件, 然后reader进程从a.txt文件中读取数据, 这就实现了进程间的通信。 我当时读书的时候, 就是这么干的。 在学校阶段, 确实解决了当时的问题, 靠谱。 但在公司, 谁敢这么搞?

       共享内存也是采用了类似的思路, 只不过, 共享的不是文件, 而是内存。 就是如此简单。

 

       话不多说, 来看点代码:

 

#include 
#include
#include
#include
#include
int main(){ int shmid = shmget((key_t)1234, 100, 0666|IPC_CREAT); printf("shmid %d\n", shmid); return 0;}

       key是1234, 对应的16进制是0x000004d2,  100是设定的共享内存大小。 我们看看结果:

 

 

xxxxxx:~/network> ipcs------ Shared Memory Segments --------key        shmid      owner      perms      bytes      nattch     status      0x115fd81a 32768      root      666        4096       2                       0x294b8556 65537      root      666        13497727   1                       ------ Semaphore Arrays --------key        semid      owner      perms      nsems     0x0000870a 0          root      666        1         0x00008707 32769      root      666        1         0x00008709 65538      root      666        1         0x0000870b 98307      root      666        1         ------ Message Queues --------key        msqid      owner      perms      used-bytes   messages    xxxxxx:~/network>xxxxxx:~/network>xxxxxx:~/network>xxxxxx:~/network> ./testshmid 294915xxxxxx:~/network> ipcm-bash: ipcm: command not foundxxxxxx:~/network> ipcs------ Shared Memory Segments --------key        shmid      owner      perms      bytes      nattch     status      0x115fd81a 32768      root      666        4096       2                       0x294b8556 65537      root      666        13497727   1                       0x000004d2 294915     xxxxxx    666        100        0                       ------ Semaphore Arrays --------key        semid      owner      perms      nsems     0x0000870a 0          root      666        1         0x00008707 32769      root      666        1         0x00008709 65538      root      666        1         0x0000870b 98307      root      666        1         ------ Message Queues --------key        msqid      owner      perms      used-bytes   messages    xxxxxx:~/network>

       可以看到, 运行程序前, 没有用户xxxxxx对应的共享内存, 运行后, 创建了一块共享内存, 其信息和我们在程序中设置的信息完全一致。

 

       这里要注意一下几点(有兴趣的同学可以多多尝试)

       1.  调用shmget的时候, 如果共享内存key已经存在, 则不是创建一块新共享内存, 而是返回已经存在的共享内存。

       2.  进程退出后, 共享内存不会释放, 需要调用shmctr函数, 或者用ipcrm命令才可释放。

       3.  ipcs和ipcrm要用熟。

       

       有点迫不及待看共享内存的实际代码了, 一起来看看:

       writer.cpp

 

#include 
#include
#include
#include
#include
#define TEST_SIZE 2048typedef struct _BOX{ int flag; char szMsg[TEST_SIZE];}Box;int main(){ int shmid = shmget((key_t)1234, sizeof(Box), 0666|IPC_CREAT); void *shm = shmat(shmid, (void*)0, 0); Box *pBox = (Box*)shm; pBox->flag = 0; int i = 0; while(1) { while(pBox->flag == 0) { getchar(); snprintf(pBox->szMsg, sizeof(pBox->szMsg), "hello %d", ++i); printf("write msg is [%s]\n", pBox->szMsg); pBox->flag = 1; } } shmdt(shm); return 0;}

      reader.cpp的内容为:

 

 

#include 
#include
#include
#include
#include
#define TEST_SIZE 2048typedef struct _BOX{ int flag; char szMsg[TEST_SIZE];}Box;int main(){ int shmid = shmget((key_t)1234, sizeof(Box), 0666|IPC_CREAT); void *shm = shmat(shmid, 0, 0); Box *pBox = (Box*)shm; while(1) { if(pBox->flag == 1) { printf("msg from writer is [%s]\n", pBox->szMsg); pBox->flag = 0; } } shmdt(shm); shmctl(shmid, IPC_RMID, 0); return 0;}

 

 

      先启动writer,  再启动reader,   于是乎, writer逐渐往共享内存中写数据(按enter键), reader不断读共享内存的数据, 结果为(如下只给出reader端的结果):

 

 

 

msg from writer is [hello 1]msg from writer is [hello 2]msg from writer is [hello 3]msg from writer is [hello 4]msg from writer is [hello 5]msg from writer is [hello 6]msg from writer is [hello 7]msg from writer is [hello 8]msg from writer is [hello 9]msg from writer is [hello 10]

       可见, 在writer端不断按enter键盘的时候, 消息源源不断地“流向”了reader, 就是如此简单。 至于代码中的函数, 直接man一下, 一切就一目了然了。

 

 

       共享内存是最快的进程间通信方式, 没有之一。 但同步的问题, 还得应用程序自己解决。

       OK,  不多说。

 

 

转载地址:http://ujwti.baihongyu.com/

你可能感兴趣的文章
JavaScript substr() 方法
查看>>
JavaScript slice() 方法
查看>>
JavaScript substring() 方法
查看>>
HTML 5 新的表单元素 datalist keygen output
查看>>
(转载)正确理解cookie和session机制原理
查看>>
jQuery ajax - ajax() 方法
查看>>
将有序数组转换为平衡二叉搜索树
查看>>
最长递增子序列
查看>>
从一列数中筛除尽可能少的数,使得从左往右看这些数是从小到大再从大到小...
查看>>
判断一个整数是否是回文数
查看>>
经典shell面试题整理
查看>>
腾讯的一道面试题—不用除法求数字乘积
查看>>
素数算法
查看>>
java多线程环境单例模式实现详解
查看>>
将一个数插入到有序的数列中,插入后的数列仍然有序
查看>>
在有序的数列中查找某数,若该数在此数列中,则输出它所在的位置,否则输出no found
查看>>
万年历
查看>>
作为码农你希望面试官当场指出你错误么?有面试官这样遭到投诉!
查看>>
好多程序员都认为写ppt是很虚的技能,可事实真的是这样么?
查看>>
如果按照代码行数发薪水会怎样?码农:我能刷到公司破产!
查看>>