共享内存是在两个正在运行的进程之间传递数据的一种非常有效的方式。但是他并没有为我们提供同步的机制,因此我们需要用其他的机制来同步对共享内存的访问。对共享内存访问的同步控制必须要由程序员来控制。一种典型的应用是,我们用共享内存来提供对大块内存区域的有效访问,同时通过传递小消息来同步对该内存的访问。如果一个进程向共享内存段写入了数据,所做的改动立即被其他可以访问该共享内存的进程看到。
接口函数:
shmget函数创建共享内存;
第一次创建共享内存段时,他不能被任何进程访问。要想启动对该共享内存的访问,必须将其连接到一个进程的地址空间中。shmat函数来完成这部分工作,第二个参数一般设为0,表示让系统来选择共享内存出现的地址。
下面来看个例程,该例程第一个进程将创建一个共享内存段,然后把写到他里面的数据显示出来;第二个例程将连接一个已有的共享内存段,并允许我们向其写入数据。
srand((unsigned int)getpid());
//创建共享内存段,该共享内存段由key_t类型参数命名
shm_id = shmget((key_t)1234,sizeof(struct shared_use_at),0666|IPC_CREAT);
if(shm_id == -1)
{
fprintf(stderr,"shared memory create failed!");
exit (1);
}
//把创建好的内存段连接到进程地址空间中
shared_memory = shmat(shm_id,0,0);
if(shared_memory == (void *)-1)
{
fprintf(stderr,"shmat failed!");
exit (1);
}
shared_stuff = (struct shared_use_at *)shared_memory;
shared_stuff->write_by_you = 0;
while(running)
{
//如果标志位1,则显示共享内存段的数据,并且标志位清0
if(shared_stuff->write_by_you)
{
printf("you wrote:%s",shared_stuff->some_text);
sleep(rand()%4);
shared_stuff->write_by_you = 0;
if(strncmp(shared_stuff->some_text,"end",3) == 0)
running = 0;
}
}
//共享内存被分离
if(shmdt(shared_memory) == -1)
{
fprintf(stderr,"shmtd failed!");
exit (1);
}
//删除内存共享段
if(shmctl(shm_id,IPC_RMID,0) == -1)
{
fprintf(stderr,"shmctl(IPC_RMID) failed!");
exit (1);
}
return 0;
}
进程2:
/*生产者程序,这段程序向消费者程序输入数据*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "shm.h"
int main()
{
int shm_id;
struct shared_use_at *shared_stuff;
void *shared_memory = (void *)0;
char buffer[BUFSIZ];
int running = 1;
srand((unsigned int)getpid());
//创建共享内存段,该共享内存段由key_t类型参数命名
shm_id = shmget((key_t)1234,sizeof(struct shared_use_at),0666|IPC_CREAT);
if(shm_id == -1)
{
fprintf(stderr,"shared memory create failed!");
exit (1);
}
//把创建好的内存段连接到进程地址空间中
shared_memory = shmat(shm_id,0,0);
if(shared_memory == (void *)-1)
{
fprintf(stderr,"shmat failed!");
exit (1);
}
shared_stuff = (struct shared_use_at *)shared_memory;
while(running)
{
//标志为1,表示进程1会显示数据,等待他
while(shared_stuff->write_by_you == 1)
{
sleep(1);
printf("waiting for client.../n");
}
//当标志为0时,表示进程1已经显示了数据,向共享内存段写数据
printf("enter some text:");
fgets(buffer,BUFSIZ,stdin);
strncpy(shared_stuff->some_text,buffer,TEXT_SZ);
//写好了,置位标志位
shared_stuff->write_by_you = 1;
//判断结束附
if(strncmp(buffer,"end",3) == 0)
{
running = 0;
}
}
//共享内存被分离
if(shmdt(shared_memory) == -1)
{
fprintf(stderr,"shmtd failed!");
exit (1);
}
return 0;
}
运行结果:
$ ./shm1 &
[1] 2604
[sea@localhost ~]$ ./shm2
enter some text:see you
you wrote:see you
waiting for client...
waiting for client...
waiting for client...
waiting for client...
enter some text:see me
you wrote:see me
waiting for client...
waiting for client...
enter some text:俄^H恩
you wrote:俄
waiting for client...
waiting for client...
waiting for client...
enter some text:end
you wrote:end
[sea@localhost ~]$