📄 reader_writer3.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 + -