linux进程通信(一)--共享内存+信号量

/*server.c:向共享内存中写入People*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int main()
{
	struct People{
		char name[10];
		int age;
	};
	
	int semid;
	int shmid;
	key_t semkey;
	key_t shmkey;
	semkey=ftok("server.c",0);
	shmkey=ftok("client.c",0);
	
	/*创建共享内存和信号量的IPC*/
	semid=semget(semkey,1,0666|IPC_CREAT);
	if(semid==-1)
	printf("creat sem is fail\n");
	shmid=shmget(shmkey,1024,0666|IPC_CREAT);
	if(shmid==-1)
	printf("creat shm is fail\n");
	
	/*设置信号量的初始值,就是资源个数*/
	union semun{
		int val;
		struct semid_ds *buf;
		ushort *array;
	}sem_u;
	
	sem_u.val=1;
	semctl(semid,0,SETVAL,sem_u);
	
	/*将共享内存映射到当前进程的地址中,之后直接对进程中的地址addr操作就是对共享内存操作*/
	
	struct People * addr;
	addr=(struct People*)shmat(shmid,0,0);
	if(addr==(struct People*)-1)
	printf("shm shmat is fail\n");
	
	/*信号量的P操作*/
	void p()
	{
		struct sembuf sem_p;
		sem_p.sem_num=0;
		sem_p.sem_op=-1;
		if(semop(semid,&sem_p,1)==-1)
		printf("p operation is fail\n");		
	}

	/*信号量的V操作*/
	void v()
	{
		struct sembuf sem_v;
		sem_v.sem_num=0;
		sem_v.sem_op=1;
		if(semop(semid,&sem_v,1)==-1)
		printf("v operation is fail\n");
	}
	
	/*向共享内存写入数据*/
	p();
	strcpy((*addr).name,"xiaoming");
/*注意:①此处只能给指针指向的地址直接赋值,不能在定义一个  struct People people_1;addr=&people_1;因为addr在addr=(struct People*)shmat(shmid,0,0);时,已经由系统自动分配了一个地址,这个地址与共享内存相关联,所以不能改变这个指针的指向,否则他将不指向共享内存,无法完成通信了。
注意:②给字符数组赋值的方法。刚才太虎了。。*/
	(*addr).age=10;
	v();
	
	/*将共享内存与当前进程断开*/
	if(shmdt(addr)==-1)
	printf("shmdt is fail\n");	
	
}
/*client.c:从共享内存中读出People*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int main()
{
	int semid;
	int shmid;
	key_t semkey;
	key_t shmkey;
	semkey=ftok("server.c",0);
	shmkey=ftok("client.c",0);
	
	struct People{
		char name[10];
		int age;
	};

	/*读取共享内存和信号量的IPC*/	
	semid=semget(semkey,0,0666);
	if(semid==-1)
	printf("creat sem is fail\n");
	shmid=shmget(shmkey,0,0666);
	if(shmid==-1)
	printf("creat shm is fail\n");
	
	/*将共享内存映射到当前进程的地址中,之后直接对进程中的地址addr操作就是对共享内存操作*/
	struct People * addr;
	addr=(struct People*)shmat(shmid,0,0);
	if(addr==(struct People*)-1)
	printf("shm shmat is fail\n");
	
	/*信号量的P操作*/
	void p()
	{
		struct sembuf sem_p;
		sem_p.sem_num=0;
		sem_p.sem_op=-1;
		if(semop(semid,&sem_p,1)==-1)
		printf("p operation is fail\n");		
	}
	
	/*信号量的V操作*/
	void v()
	{
		struct sembuf sem_v;
		sem_v.sem_num=0;
		sem_v.sem_op=1;
		if(semop(semid,&sem_v,1)==-1)
		printf("v operation is fail\n");
	}
	
	/*从共享内存读出数据*/
	p();
	printf("name:%s\n",addr->name);
	printf("age:%d\n",addr->age);
	v();
	
	/*将共享内存与当前进程断开*/
	if(shmdt(addr)==-1)
	printf("shmdt is fail\n");
	
	/*IPC必须显示删除。否则会一直留存在系统中*/
	if(semctl(semid,0,IPC_RMID,0)==-1)
	printf("semctl delete error\n");
	if(shmctl(shmid,IPC_RMID,NULL)==-1)
	printf("shmctl delete error\n");
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值