通过共享内存,实现两个进程A,B之间的通信

进程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值决定是否往共享内存中写入数据。

 

在Unix/Linux系统中,可以通过System V的共享内存实现两个进程间的通信共享内存是最快的IPC(进程通信)机制,因为它允许两个或多个进程共享一个给定的存储区。以下是使用C语言在Linux环境下创建两个程序来实现进程共享内存通信的简单例子。 第一个程序:创建共享内存并写入数据 ```c #include <stdio.h> #include <stdlib.h> #include <sys/shm.h> #include <sys/stat.h> #include <unistd.h> #define SHM_SIZE 1024 int main() { int shm_id; key_t key = 1234; // 这是共享内存的键值 // 创建共享内存段 shm_id = shmget(key, SHM_SIZE, IPC_CREAT | 0666); if (shm_id == -1) { perror("shmget failed"); exit(1); } // 将共享内存附加到当前进程的地址空间 char *str = (char*)shmat(shm_id, NULL, 0); if (str == (char*)-1) { perror("shmat failed"); exit(1); } // 写数据到共享内存 sprintf(str, "Hello, World!"); // 分离共享内存 shmdt(str); return 0; } ``` 第二个程序:读取共享内存中的数据 ```c #include <stdio.h> #include <stdlib.h> #include <sys/shm.h> #include <sys/stat.h> #include <unistd.h> #define SHM_SIZE 1024 int main() { int shm_id; key_t key = 1234; // 使用相同的键值 // 获取共享内存段 shm_id = shmget(key, SHM_SIZE, 0); if (shm_id == -1) { perror("shmget failed"); exit(1); } // 将共享内存附加到当前进程的地址空间 char *str = (char*)shmat(shm_id, NULL, 0); if (str == (char*)-1) { perror("shmat failed"); exit(1); } // 打印共享内存中的数据 printf("Shared memory data: %s\n", str); // 分离共享内存 shmdt(str); // 删除共享内存段 shmctl(shm_id, IPC_RMID, NULL); return 0; } ``` 在这两个程序中,第一个程序创建了一个共享内存段,写入了一条消息,然后分离了共享内存。第二个程序附加到了同一个共享内存段,读取了消息,并在完成后删除了共享内存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值