进程A:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <error.h>
#include <stdlib.h>
#include <string.h>
#define SHM_SIZE 4096
#define SHM_MODE (SHM_R | SHM_W) /* user read/write */
/*定义一个结构体*/
typedef struct
{
char buf[255];
int tag;
}shminfo;
int main(void)
{
int shmid;
char *shmptr;
shminfo *pnode;
if ( (shmid = shmget(0x44, SHM_SIZE, SHM_MODE | IPC_CREAT)) < 0)
perror("shmget");
if ( (shmptr = shmat(shmid, 0, 0)) == (void *) -1)
perror("shmat");
pnode = (shminfo *)shmptr;
memset(pnode,0,sizeof(shminfo)); ));/*这一句非常重要,为什么呢?这涉及到
下面while循环中的内容,在下面的while中,我们约定当tag的标志为0x12时,进程
B读取进程A往共享内存中所写的内容,如果不用这个函数,那么在while循环中,
就无法进入if语句,那么在写过一次数据之后就无法在写入其它数据了。(我当时
不知道怎么回事,写入一次后就出现这种情况,后来又把这条语句注释掉,可是
再也没有碰到过这种情况,后面我仔细思考了一下,在进程B读取数据完后,我
在后面加了memset这条语句,按道理是不会出现这种情况了,当时真不知道是
怎么回事了,下次要及时记录。)*/
/* 往共享内存写数据 */
while(1)
{
sleep(1);
if(pnode->tag!=0x12)
{
printf("请输入要写进共享内存中的数据:\n");
scanf("%s",pnode->buf);
pnode->tag = 0x12;
}
}
exit(0);
}
进程B:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <error.h>
#include <stdlib.h>
#include <string.h>
#define SHM_SIZE 4096
#define SHM_MODE (SHM_R|SHM_W|IPC_CREAT)
typedef struct
{
char buf[255];
int tag;
}shminfo;
int main(void)
{
int shmid;
char *shmptr;
shminfo *pnode;
if((shmid = shmget(0x44,SHM_SIZE,SHM_MODE|IPC_CREAT))<0)
perror("shmget");
if ((shmptr = shmat(shmid,0,0))==(void*)-1)
perror("shmat");
pnode = (shminfo *)shmptr;
while(1)
{
sleep(1);
if(pnode->tag==0x12)
{
printf("从共享内存中读出的数据是:%s\n",pnode->buf);
memset(pnode,0x00,sizeof(shminfo));
}
}
exit(0);
}
在解释这两个进程之前,先解释一下memset这个函数,它的作用是在一段内存中填
充某个给定的值,它是对较大的结构体或者数组进行清零操作的一种最快方法。举个例
子,如果你要把char a[20]这个数组清零,就可以使用memset(a,0,20)。这样就把这
个数组清零了。 现在解释一下这两个进程间到底在干什么?进程A通过shmget这个函数
创建一块新的内存空间,再通过shmat把这个新建的内存空间挂载起来,即允许其他进程
对这个新建的内存空间访问。
进程A,B实现的功能是,进程A往共享内存中写数据,约定一个tag,当这个tag为某个
特定的值时,进程B读取数据(进程B每隔一段时间扫描一次),B读完之后,再修改这个
tag值,告诉进程A(进程A每隔一段时间扫描一次),我已经读完了,进程A通过判断这
个tag值决定是否往共享内存中写入数据。