⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reader_writer3.c

📁 是一个linux下的共享内存文件
💻 C
字号:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <errno.h>
#include <strings.h>
#include <signal.h>#include <signal.h>#include <sys/time.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/stat.h>#include <fcntl.h>#define FILENAME "/home/njucslw/reader_writer/stat"
 
#if defined(__GNU_LIBRARY__)&& !defined (_SEM_SEMUN_UNDEFINED)

#else

union semun{
  int val;
  struct semid_ds *buf;
  unsigned short int *array;
  struct seminfo *__buf;
};
#endif

#define SHMDATASIZE 1000
#define BUFFERSIZE (SHMDATASIZE - sizeof(int))

#define SN_READ 0
#define SN_WRITE 1
#define SN_LOCK 2

int Semid=0;

void reader(int shmid);
void writer(int shmid);
int masterinit(void);
char *standardinit(int shmid,int *semid);
void delete(void);
void sigdelete(int signum);
void locksem(int semid,int semnum);
void unlocksem(int semid,int semnum);
void waitzero(int semid,int semnum);
void write0(int shmid,int semid,char *buffer);

int mysemget(key_t key,int nsems,int semflg);
int mysemctl(int semid,int semnum,int cmd,union semun arg);
int mysemop(int semid,struct sembuf *sops,unsigned nsops);
int myshmget(key_t key,int size,int shmflg);
void *myshmat(int shmid,const void *shmaddr,int shmflg);
int myshmctl1(int shmid,int cmd,struct shmid_ds *buf);

int main(int argc,char *argv[]){

  char selection[3];
  int shmid;

  if(argc<2){
    shmid=masterinit();
  }else{
    shmid=atoi(argv[1]);
  }

  printf("do you want a writer(1) or reader(2)?");
  fgets(selection,sizeof(selection),stdin);

  switch(selection[0]){
      case '1':writer(shmid);break;
      case '2':reader(shmid);break;
      default:printf(" invalid choice,quit \n");
  }

  return 0;
}
//the number of the readers is at most 999;
void reader(int shmid){
  	int semid;
  	char *buffer;	int fd;	int rc=0;	char ptr[3];	int  RC[3];
	/////////////////////////////////////////////////////////////////////////////////////////////
  	buffer=standardinit(shmid,&semid);
  	printf("waiting for locking semaphore SN_LOCK...");
  	fflush(stdout);
  	locksem(semid,SN_LOCK);
  	printf("finish \n");		fd=open(FILENAME,O_RDWR);	if(fd<0)	{		printf("Open file stat failed!\n");		return;	}	read(fd,ptr,3);	close(fd);	rc=atoi(ptr);	rc++;	RC[0]=rc/100;	RC[1]=(rc/10)%10;	RC[2]=rc%10;	int i;	for(i=0;i<3;i++)	{			switch(RC[i])		{			case 0:ptr[i]='0';break;			case 1:ptr[i]='1';break;			case 2:ptr[i]='2';break;			case 3:ptr[i]='3';break;			case 4:ptr[i]='4';break;			case 5:ptr[i]='5';break;			case 6:ptr[i]='6';break;			case 7:ptr[i]='7';break;			case 8:ptr[i]='8';break;			case 9:ptr[i]='9';break;		}	}	fd=open(FILENAME,O_RDWR);	write(fd,ptr,3);	close(fd);	if(rc==1)	{		printf("\n wait for writer to input information...");
  		fflush(stdout);
  		locksem(semid,SN_WRITE);
  		printf("finish \n");	}	unlocksem(semid,SN_LOCK);		int k=1;	do	{		printf("received information: %s \n",buffer);		char input[3];
    		printf("\n Do you want to quit?Y/N:");
    		fgets(input,sizeof(input),stdin);

   		switch(input[0])		{
    			case 'Y':k=0;break;
    			case 'N':k=1;break;
    		}	}while(k);	
  	fflush(stdout);
  	locksem(semid,SN_LOCK);
	fd=open(FILENAME,O_RDWR);	if(fd<0)	{		printf("Open file stat failed!\n");		return;	}	read(fd,ptr,3);	rc=atoi(ptr);	rc--;	RC[0]=rc/100;	RC[1]=(rc/10)%10;	RC[2]=rc%10;	for(i=0;i<3;i++)	{			switch(RC[i])		{			case 0:ptr[i]='0';break;			case 1:ptr[i]='1';break;			case 2:ptr[i]='2';break;			case 3:ptr[i]='3';break;			case 4:ptr[i]='4';break;			case 5:ptr[i]='5';break;			case 6:ptr[i]='6';break;			case 7:ptr[i]='7';break;			case 8:ptr[i]='8';break;			case 9:ptr[i]='9';break;		}	}	close(fd);	fd=open(FILENAME,O_RDWR);	write(fd,ptr,3);	close(fd);	if(rc==0)	{
  		unlocksem(semid,SN_WRITE);	}	unlocksem(semid,SN_LOCK);	/////////////////////////////////////////////////////////////////////////////////////////////
}

void writer(int shmid){
  int semid;
  char *buffer;

  buffer=standardinit(shmid,&semid);

  printf("\n writer begin to run,the id of share memory is %d,the semaphore is %d \n",shmid,semid);

  while(1){
    char input[3];

    printf("\n menu \n 1.send a message \n");
    printf(" 2.quit \n");
    printf("input your choice (1-2):");
    
    fgets(input,sizeof(input),stdin);

    switch(input[0]){
    case '1':write0(shmid,semid,buffer);break;
    case '2':exit(0);break;
    }
  }
}

char *standardinit(int shmid,int *semid){
    void *shmdata;
    char *buffer;
 
    shmdata=myshmat(shmid,0,0);

    *semid=*(int *)shmdata;
    buffer=shmdata+sizeof(int);

    return buffer;
}

int masterinit(void){
    union semun sunion;
    int semid,shmid;
    void *shmdata;

    semid=mysemget(IPC_PRIVATE,3,SHM_R|SHM_W);

    Semid=semid;

    //atexit(&delete);
    //signal(SIGINT,&sigdelete);

    sunion.val=1;
    mysemctl(semid,SN_READ,SETVAL,sunion);
    mysemctl(semid,SN_LOCK,SETVAL,sunion);
    sunion.val=1;
    mysemctl(semid,SN_WRITE,SETVAL,sunion);

    shmid=myshmget(IPC_PRIVATE,SHMDATASIZE,IPC_CREAT|SHM_R|SHM_W);

    shmdata=myshmat(shmid,0,0);

    myshmctl(shmid,IPC_RMID,NULL);

    *(int *)shmdata=semid;

    printf("*** begin to run,and semaphore id is %d \n",shmid);

    return shmid;
}

void delete(void){
  printf("\n quit;delete the semaphore %d\n",Semid);

  if(mysemctl(Semid,0,IPC_RMID,(union semun) 0)==-1){
    printf("Error releasing semaphore.\n");
  }
}

void sigdelete(int signum){

  exit(0);
}

void locksem(int semid,int semnum){
  struct sembuf sb;

  sb.sem_num=semnum;
  sb.sem_op=-1;
  sb.sem_flg=SEM_UNDO;

  mysemop(semid,&sb,1);
}

void unlocksem(int semid,int semnum){
  struct sembuf sb;

  sb.sem_num=semnum;
  sb.sem_op=1;
  sb.sem_flg=SEM_UNDO;

  mysemop(semid,&sb,1);
}

void waitzero(int semid,int semnum){
  struct sembuf sb;

  sb.sem_num=semnum;
  sb.sem_op=0;
  sb.sem_flg=0;
  mysemop(semid,&sb,1);
}

void write0(int shmid,int semid,char *buffer){		/////////////////////////////////////////////////////////////////////////////////////////////
  	printf("wait for locking semaphore SN_LOCK... ");
  	fflush(stdout);
  	locksem(semid,SN_WRITE);
	printf("finish;\n");
  	printf("please input information:");
  	fgets(buffer,BUFFERSIZE,stdin);

  	unlocksem(semid,SN_WRITE);	/////////////////////////////////////////////////////////////////////////////////////////////////
}

int mysemget(key_t key,int nsems,int semflg){
  int retval;

  retval=semget(key,nsems,semflg);
  if(retval==-1){
    printf("semget key %d,nsems %d failed: %s ",key,nsems,strerror(errno));
    exit(255);
  }
  return retval;
}

int mysemctl(int semid,int semnum,int cmd,union semun arg){
  int retval;

  retval=semctl(semid,semnum,cmd,arg);
  if(retval==-1){
    printf("semctl semid %d,semnum %d,cmd %d failed:%s",semid,semnum,cmd,strerror(errno));
    exit(255);
  }
  return retval;
}

int mysemop(int semid,struct sembuf *sops,unsigned nsops){
  int retval;

  retval=semop(semid,sops,nsops);
  if(retval==-1){
    printf("semop semid %d (%d operations) failed:%s",semid,nsops,strerror(errno));
    exit(255);
  }

  return retval;
}

int myshmget(key_t key,int size,int shmflg){
  int retval;

  retval=shmget(key,size,shmflg);
  if(retval==-1){
    printf("shmget key %d,size %d failed:%s",key,size,strerror(errno));
    exit(255);
  }

  return retval;
}

void *myshmat(int shmid,const void *shmaddr,int shmflg){
  void *retval;

  retval=shmat(shmid,shmaddr,shmflg);
  if(retval==(void*)-1){
    printf("shmat shmid %d failed:%s",shmid,strerror(errno));
    exit(255);
  }

  return retval;
}

int myshmctl(int shmid,int cmd,struct shmid_ds *buf){
  int retval;

  retval=shmctl(shmid,cmd,buf);
  if(retval==-1){

    printf("shmctl shmid %d,cmd %d failed:%s",shmid,cmd,strerror(errno));
    exit(255);
  }

  return retval;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -