linux进程通信-共享内存

共享内存是进程间通信中最简单的方式之一。共享内存在各种进程间通信方式中具有最高的效率。因为系统内核没有对访问共享内存进行同步,您必须提供自己的同步措施。解决这些问题的常用方法是通过使用信号量进行同步。

1.函数shmget
我们使用函数shmget来获得一个共享内存标识符

#include<key_t key,size_t size,int flag>
返回值:成功返回ID,出错返回-1

参数key_t:不同进程之间是通过这个数值来联系的。
参数size:表示该共享存储段的长度,创建一个新段必须指定size的值,如果引用一个先存的段,该值为0;
参数flag:表示权限

2.函数shmctl
使用函数shmctl来执行多种操作

#include<sys.shm.h>
int shmget(int shmid,int cmd,shtruct shmid_ds  *buf);
返回值:成功返回0,出错返回-1

参数cmd指定几个命令,包括IPC_RMID删除等

3.函数shmat
一旦创建了一个共享存储段,进程就调用shmat将其连接到它的地址空间去。

#include<sys/shm.h>
int *shmat(int shmid,const void *addr,int flag);
返回值:成功返回指向共享存储段的指针;若出错,返回-1

共享存储段连接到进程的哪个地址上与addr参数,以及flag中是否指定SHM_RND有关。
1)若addr为0,则此段连接到由内核选择的第一个可用地址上,这是推荐使用的方式
2)若addr非0,并且没有指定SHM_RND,则此段连接到addr所指定的地址上
参数flag:若指定了SHM_RDONLY,则以只读方式打开,否则以读写方式打开。

4.函数shmdt
当共享内存的操作结束时,则调用shmdt来与该段分离,但并不是删除

#include<sys/shm.h>
int shmdt(const void *addr);
返回值:成功返回0,失败返回-1

参数address,是函数shmat的返回值。

例程往共享内存写数据

#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <string.h>  
#include <sys/shm.h>  
#include "shmdata.h"  
 
struct shared_use_st  
{  
    
	int written;                                                //标志读写
	
    char text[512];                                         //缓存数据                 
	
};


int main()
{
	int running=1;
	char buffer[512];
	int shmid;
	void *shm=NULL;
	struct shared_use_st *shared = NULL; 
	shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);     //创建一个共享内存
	if(shmid==-1)
	{

		fprintf(stderr,"shmget failed\n");
		exit(1);
	}
	shm=shmat(shmid,0,0);                                                                                    //连接到当前进程的地址
	if(shm==(void *)-1)
	{
		fprintf(stderr,"shmat failed\n");
		exit(1);
		
	}
	shared=(struct shared_use_st *)shm;
	
	while(running)
	{
		if(shared->written!=0)                              //当前不可写
		{
			sleep(1);

		}
		
		fgets(buffer,512,stdin);                            //写入数据
		strncpy(shared->text,buffer,512);
		shared->written=1;
		if(strncmp(buffer,"end",3)==0)
			running=0;
	
	}
	
	  if(shmdt(shm) == -1)  
    {  
        fprintf(stderr, "shmdt failed\n");  
        exit(EXIT_FAILURE);  
    }  
    sleep(2);  
    exit(0); 
	
}

读取共享内存的例程

#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <sys/shm.h>  

 
struct   shared_use_st{
	int written;                            //作为一个读或写的标志。 0表示可写,非0表示可读
	char text[2048];                        //数据缓存在这里
	
	
}


int main()
{
	int shmid;
	int running=1;
	void *shm = NULL;//分配的共享内存的原始首地址  
    struct shared_use_st *shared;//指向shm 
	
	
	shmid=shmget(key_t(1234),sizeof(struct shared_use_st),0666|IPC_CREAT);        //创建一个共享存储段
	if(shmid<0)
	{
		fprintf(stderr,"shmid failed\n");
		exit(1);
	}
	shm=shmat(shmid,0,0);                                                   //将共享内存链接到当前的进程的地址空间
	if(shm==(void *)-1)
	{
		fprintf(stderr,"shmat failed\n");
		exit(1);
	}
	
	shared=(struct shared_use_st * )shm;
	shared->written=0;                                               
	
	while(runing)
	{
		if(shared->written!=0)                                        //当前无进程写,可读
		{
			printf("%s",shared->text);
			sleep(3);
			shared->written=0;                                        //读取完后设置为可写
			if(strncmp(shared->text, "end", 3) == 0)  
                running = 0; 
		
		}
		else
		sleep(1);		
	}
	if(shmdt(shm) == -1)                                             //从当前进程分离
    {  
        fprintf(stderr, "shmdt failed\n");  
        exit(1);  
    }
	
	if(shmctl(shmid, IPC_RMID, 0) == -1)                //删除
    {  
        fprintf(stderr, "shmctl(IPC_RMID) failed\n");  
        exit(1);  
    }  
    exit(0);  
	

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值