deepfuture@deepfuture-laptop:~/private/mytest$ gcc -std=gnu99 -o testshm testshm.c
testshm.c: In function ‘main’:
testshm.c:38: warning: implicit declaration of function ‘semget’
testshm.c:41: warning: implicit declaration of function ‘exit’
testshm.c:41: warning: incompatible implicit declaration of built-in function ‘exit’
testshm.c:45: warning: implicit declaration of function ‘semctl’
testshm.c:48: warning: incompatible implicit declaration of built-in function ‘exit’
testshm.c:51: warning: implicit declaration of function ‘shmget’
testshm.c:54: warning: incompatible implicit declaration of built-in function ‘exit’
testshm.c:57: warning: implicit declaration of function ‘shmat’
testshm.c:60: warning: incompatible implicit declaration of built-in function ‘exit’
testshm.c:63: warning: implicit declaration of function ‘memset’
testshm.c:63: warning: incompatible implicit declaration of built-in function ‘memset’
testshm.c:69: warning: incompatible implicit declaration of built-in function ‘exit’
testshm.c:78: warning: implicit declaration of function ‘strlen’
testshm.c:78: warning: incompatible implicit declaration of built-in function ‘strlen’
testshm.c:85: warning: implicit declaration of function ‘memcpy’
testshm.c:85: warning: incompatible implicit declaration of built-in function ‘memcpy’
testshm.c:92: warning: implicit declaration of function ‘semop’
testshm.c:95: warning: incompatible implicit declaration of built-in function ‘exit’
testshm.c:119: warning: incompatible implicit declaration of built-in function ‘strlen’
testshm.c:124: warning: incompatible implicit declaration of built-in function ‘exit’
testshm.c:132: warning: implicit declaration of function ‘wait’
testshm.c:134: warning: implicit declaration of function ‘shmdt’
testshm.c:139: warning: implicit declaration of function ‘shmctl’
testshm.c:142: warning: incompatible implicit declaration of built-in function ‘exit’
deepfuture@deepfuture-laptop:~/private/mytest$ ./testshm
deepfuture.javeye.com#line 1$deepfuture
deepfuture.javeye.com#line 2$javaeye
deepfuture.javeye.com#line 3$com
deepfuture.javeye.com#line 4$deepfuture.iteye.com
deepfuture.javeye.com#line 5$Q
deepfuture.javeye.com#line 6$
退出....
deepfuture@deepfuture-laptop:~/private/mytest$ cat abc.txt
deepfuture
javaeye
com
deepfuture.iteye.com
deepfuture@deepfuture-laptop:~/private/mytest$
#include <stdio.h> #include <unistd.h> #include <linux/types.h> #include <linux/shm.h> #include <linux/sem.h> #include <linux/ipc.h> #define MAXS (1024+1) #define BUFFERSIZE 200 #define SEMID 251//信号标志 #define FILENAME "abc.txt" #define SHMKEY 241//共享内存标志 #define SHMSIZE MAXS//共享内存大小 //程序完成父进程接收键盘输入,子进程存入文件FILENAME。 //deepfuture.iteye.com int main(void){ char strbuf[MAXS]; char buf[BUFFERSIZE]; int sem_id; int shm_id; int pid; int rc,res; struct sembuf sem_op;//信号集结构 union semun sem_val;//信号量数值 char *cur; FILE *myfile; char *shm_addr; int line=1; //建立信号量集,其中只有一个信号量 deepfuture.iteye.com sem_id=semget(SEMID,1,IPC_CREAT|0600);//SEMID为为正整数,则为公共的;1为信号集的数量; if (sem_id==-1){ printf("create sem error!\n"); exit(1); } //信号量初始化 sem_val.val=0; rc=semctl(sem_id,0,SETVAL,sem_val);//设置信号量 if (rc==-1){ printf("initlize sem error!\n"); exit(1); } //建立共享内存 shm_id=shmget(SHMKEY,SHMSIZE,IPC_CREAT|0600);//参数为:标志,大小,权限 if (shm_id==-1){ printf("create shm error!\n"); exit(1); } //attach共享内存。连接共享内存 deepfuture.iteye.com shm_addr=(char *)shmat(shm_id,NULL,0);//返回共享内存地址 deepfuture.iteye.com if (!shm_addr){ printf("shmat error!\n"); exit(1); } //初始化数据 memset(shm_addr,'\0',MAXS); cur=shm_addr;//当前字符起始地址 //创建进程 pid=fork(); if (pid==-1){ printf("fork error!\n"); exit(1); } else if(pid==0){//子进程,接受键盘输入,往共享内存中写字符行 deepfuture.iteye.com int isend=0;//是否结束输入 printf("\ndeepfuture.javeye.com#line %d$",line); //自定义键盘输入时使用的SHELL外观 while((!isend)&&fgets(buf,BUFFERSIZE,stdin)!=NULL){//从shell中读入一行 line++; printf("\ndeepfuture.javeye.com#line %d$",line); //自定义键盘输入时使用的SHELL外观 if (buf[0]=='Q'&&strlen(buf)<=2){//单个字符Q表示退出输入 isend++;//退出输入 printf("\n退出....\n"); } else {//如果不是退出命令 //写共享内存 deepfuture.iteye.com memcpy(cur,buf,strlen(buf)); cur+=strlen(buf); } //写入一行,增加信号 sem_op.sem_num=0; sem_op.sem_op=1; sem_op.sem_flg=0; semop(sem_id,&sem_op,1);//操作信号量,每次+1 } *cur=-1; exit(0); } else{//父进程,从共享内存中读字符行 ,并写入文件 deepfuture.iteye.com while(1) { //读出一行,减少信号 deepfuture.iteye.com sem_op.sem_num=0; sem_op.sem_op=-1; sem_op.sem_flg=0; semop(sem_id,&sem_op,1);//操作信号量,每次-1 //deepfuture.iteye.com 读共享内存中一行 if ((*cur)==-1) break;//输入结束 int i; for (i=0;*cur!='\n';cur++,i++){ buf[i]=*cur; } cur++; buf[i]='\n'; buf[++i]=0; //写文件 FILE *fp=fopen(FILENAME,"ab"); res=fwrite(buf,strlen(buf),1,fp);//deepfuture.iteye.com 写入一个行,长度为strlen(buf),个数为1 //size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream); //size为要写入的每个数据的大小(多少字节),nmemb为要写入数据的个数。deepfuture.iteye.com if (res==-1){ perror("write error on pipe\n"); exit(1); } fclose(fp); } wait(&pid);//等待子进程结束,即用户输入完毕 //分离共享进程 if (shmdt(shm_addr)==-1){ printf("shmdt error!\n"); } //撤销共享内存,任何进程只要有权限,都可以撤销共享内存,不一定非要创建它的进程 struct shmid_ds shm_desc; if (shmctl(shm_id,IPC_RMID,&shm_desc)==-1){ printf("shmctl error!\n"); } exit(0); } }