进程间通信:用信号量实现对共享内存读写顺序的控制

这本是一道题:一本是一个全局变量来做的控制共享内存通信方式,一个已经实现的信号量通信,最终的结果是让这两个掺和在一起。用信号量来控制共享内存通信的读写顺序。

            原本信号量通信方式的函数在这是,原本的共享内存程序在这里。

            做的最新的结果是可以通信了,但是在客户端有一点点异常,就是在服务器端还没有释放信号量,但是客户端不可以获取的,这使我很疑惑。

服务器端:

#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_com.h"

#include <sys/sem.h>

#include <signal.h>
/********************************************************/
int pid,semid;
/********************************************************/

void my_func(int sign_no)
{
	if(sign_no==SIGINT)
	{
		printf("\nYes Sir,I have get SIGINT\n");
		if(semctl(semid, 0, IPC_RMID, 0)<0)
		{
			printf("semctl remove semaphore set failed\n");
			exit(EXIT_FAILURE);
		}
		printf("semctl remove semaphore set OK\n");
		exit(EXIT_FAILURE);
	}
}

int main(void)
{
    int running=1;
	void *shared_memory=(void *)0;
	struct shared_use_st *shared_stuff;
	char buffer[BUFSIZ];
	int shmid;

	signal(SIGINT, my_func);

/***************************************************************/	
	
	key_t semkey;
	if((semkey=ftok("/home", 1))<0)
	{
		printf("ftok failed\n");
		exit(EXIT_FAILURE);
	}
	printf("ftok ok, semkey=%d\n", semkey);
	
	if((semid=semget(semkey, 1, IPC_CREAT|0666))<0)
	{
		printf("semget failed\n");
		exit(EXIT_FAILURE);
	}
	printf("semget ok, semid = %d\n", semid);
	
	if((semctl(semid, 0, SETVAL, 1))<0)
	{
		printf("semctl set sermval failed\n");
		exit(EXIT_FAILURE);
	}
	printf("semctl set semval ok\n");
	
	struct sembuf p_op_buf, v_op_buf;
	p_op_buf.sem_num=0;
	p_op_buf.sem_op = -1;
	
/******************************************************************/

	/*创建共享内存*/
	shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);
	if(shmid==-1)
	{
	    fprintf(stderr,"shmget failed\n");
		exit(EXIT_FAILURE);
	}

	/*映射共享内存*/
	shared_memory=shmat(shmid,(void *)0,0);
	if(shared_memory==(void *)-1)
	{
	    fprintf(stderr,"shmat failed\n");
		exit(EXIT_FAILURE);
	}
	printf("Memory attached at %X\n",(int)shared_memory);

	/*让结构体指针指向这块共享内存*/
	shared_stuff=(struct shared_use_st *)shared_memory;

	/*循环的向共享内存中写数据,直到写入的为“end”为止*/
	while(running)
	{
/******************************************************************************/
		//获取信号量
		if(semop(semid, &p_op_buf, 1)<0)
		{
	   	printf("semop failed\n");
	   	exit(EXIT_FAILURE);
		}
		printf("shm2 get the semaphore\n");
/******************************************************************************/
		
		printf("Ener some text:");
		fgets(buffer,BUFSIZ,stdin);
		strncpy(shared_stuff->some_text,buffer,TEXT_SZ);
		shared_stuff->written_by_you=1;
		if(strncmp(buffer,"end",3)==0)
		{
		    running=0;  //结束循环
		}

/*****************************************************************************/
		//释放信号量
		v_op_buf.sem_num = 0;
		v_op_buf.sem_op = 1;
		v_op_buf.sem_flg = 0;
		if(semop(semid, &v_op_buf, 1)<0)
		{
			printf("semop release semaphore failed\n");
			exit(EXIT_FAILURE);
		}
		printf("semop release semaphore ok\n");
/*****************************************************************************/
	}

	/*删除共享内存*/
	if(shmdt(shared_memory)==-1)
	{
	    fprintf(stderr,"shmdt failed\n");
		exit(EXIT_FAILURE);
	}
	exit(EXIT_SUCCESS);
}


客户端:

#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_com.h"

#include <sys/sem.h>

int main(void)
{
    int running=1;
	void *shared_memory=(void *)0;
	struct shared_use_st *shared_stuff;
	int shmid;
/***************************************************************/	
	int pid,semid;
	key_t semkey;
	if((semkey=ftok("/home", 1))<0)
	{
		printf("ftok failed\n");
		exit(EXIT_FAILURE);
	}
	printf("ftok ok, semkey=%d\n", semkey);
	
	if((semid=semget(semkey, 0, 0))<0)
	{
		printf("semget failed\n");
		exit(EXIT_FAILURE);
	}
	printf("semget ok, semid = %d\n", semid);
	
	if((semctl(semid, 0, SETVAL, 1))<0)
	{
		printf("semctl set sermval failed\n");
		exit(EXIT_FAILURE);
	}
	printf("semctl set semval ok\n");
	
	struct sembuf p_op_buf, v_op_buf;
	p_op_buf.sem_num=0;
	p_op_buf.sem_op = -1;
	p_op_buf.sem_flg = 0;
	
/******************************************************************/
	/*创建共享内存*/
	shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);
	if(shmid==-1)
	{
	    fprintf(stderr,"shmget failed\n");
		exit(EXIT_FAILURE);
	}

	/*映射共享内存*/
	shared_memory=shmat(shmid,(void *)0,0);
	if(shared_memory==(void *)-1)
	{
	    fprintf(stderr,"shmat failed\n");
		exit(EXIT_FAILURE);
	}
	printf("Memory attached at %X\n",(int)shared_memory);

	/*让结构体指针指向这块共享内存*/
	shared_stuff=(struct shared_use_st *)shared_memory;

	/*控制读写顺序*/
	//shared_stuff->written_by_you=0;

	/*循环的从共享内存中读数据,直到读到“end”为止*/
	while(running)
	{
/*
	   if(shared_stuff->written_by_you)
	   {
	     printf("You wrote:%s",shared_stuff->some_text);
		   sleep(1);  //读进程睡一秒,同时会导致写进程睡一秒,这样做到读了之后再写
		   shared_stuff->written_by_you=0;
		   if(strncmp(shared_stuff->some_text,"end",3)==0)
		   {
		       running=0; //结束循环
		   }
	   }
*/
/******************************************************************************/
		//获取信号量
		if(semop(semid, &p_op_buf, 1)<0)
		{
	   	printf("semop failed\n");
	   	exit(EXIT_FAILURE);
		}
		printf("shm1 get the semaphore\n");
/*******************************************************************************/

		printf("You wrote:%s",shared_stuff->some_text);
		sleep(1);  //读进程睡一秒,同时会导致写进程睡一秒,这样做到读了之后再写

		if(strncmp(shared_stuff->some_text,"end",3)==0)
		{
		   running=0; //结束循环
		}
		
/****************************************************************************/		
		//释放信号量
		v_op_buf.sem_num = 0;
		v_op_buf.sem_op = 1;
		v_op_buf.sem_flg = 0;
		if(semop(semid, &v_op_buf, 1)<0)
		{
			printf("semop release semaphore failed\n");
			exit(EXIT_FAILURE);
		}
		printf("semop release semaphore ok\n");
/*****************************************************************************/
	   
	}
/*******************************************************************************/

	/*删除共享内存*/
	if(shmdt(shared_memory)==-1)
	{
		fprintf(stderr,"shmdt failed\n");
		exit(EXIT_FAILURE);
	}
  exit(EXIT_SUCCESS);
}
以后的解决方案是先把那个信号量的程序由一个程序拆分成两个,彻底掌握信号量通信的过程。再来改造共享内存读写顺序。课程还要继续有机会再来解决吧!还一个实现上边 的方法参考 这里



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值