GREETINGS!
好久没写博客啦,最近Linux课的老师布置了一个作业蛮有意思,所以写这篇记录一下嘻嘻嘻。
- 思路:"cat m1.c | wc -c ”中间的“|”也叫管道符,就是把前面一个命令的执行结果,作为后面的命令的参数。"cat m1.c ”是读取一个文件,"wc -c ”是统计一个文件中的字节数。所以总的来说就是要实现两个进程间的通信。不是很难,直接上代码啦。必要的地方有注释,还有不明白的就留言吧。
- 管道机制:
-
#include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<stdlib.h> #include<stdio.h> #include<string.h> #include<errno.h> #include<sys/wait.h> int main(int argc,char**argv) { int pid; int fd,nbytes; int flags=O_CREAT|O_RDONLY; char buf[BUFSIZ]; char buff[BUFSIZ]; size_t rcount,wcount; int p_fd[2]; size_t n; //创建管道 if(pipe(p_fd)<0){ //返值小于0,创建失败 fprintf(stderr,"%s:pipe failed:%s\n",argv[0],strerror(errno)); exit(1); } //创建子进程 if((pid=fork())<0){ fprintf(stderr,"%s:fork of child failed:%s\n",argv[0],strerror(errno)); exit(1); } //pid==0表示子进程 else if (pid==0){ //打开文件 if((fd=open(argv[1],flags,0666))<0){ perror("Parameter ERROR!"); exit(EXIT_FAILURE); } while((nbytes=read(fd,buf,BUFSIZ))!=0){ n=strlen(buf); //向管道写数据,p_fd[1]为写 if((wcount=write(p_fd[1],buf,n))!=n){ fprintf(stderr,"%s:write failed:%s\n",argv[0],strerror(errno)); exit(0); } } close(fd); exit(EXIT_SUCCESS); }else{ //父进程 wait(0);//等待子进结束 int len=0; //从管道读数据,p_fd[0]为读 if((rcount=read(p_fd[0],buff,BUFSIZ))==0){ fprintf(stderr,"%s:read failed:%s\n",argv[0],strerror(errno)); exit(0); } buff[rcount]='\0'; len=strlen(buff); printf("%d\n",len); } close(p_fd[0]); close(p_fd[1]); exit(0); }
消息队列:
-
#include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<stdlib.h> #include<stdio.h> #include<string.h> #include<errno.h> #include<sys/wait.h> #include<sys/ipc.h> #include<sys/msg.h> //消息结构 struct msg{ long type; char text[BUFSIZ]; }; int main(int argc,char**argv) { int pid;//进程ID int qid;//队列ID int fd,nbytes; int flags=O_CREAT|O_RDONLY; char buf[BUFSIZ]; char buff[BUFSIZ]; key_t key; int len1,len2; struct msg pmsg_w,pmsg_r; key=IPC_PRIVATE; //创建队列 if((qid=msgget(key,IPC_CREAT|0666))<0){ perror("msgget:create"); exit(EXIT_FAILURE); } if((pid=fork())<0){ fprintf(stderr,"%s:fork of child failed:%s\n",argv[0],strerror(errno)); exit(1); } else if (pid==0){ if((fd=open(argv[1],flags,0666))<0){ perror("Parameter ERROR!"); exit(EXIT_FAILURE); } while((nbytes=read(fd,pmsg_w.text,BUFSIZ))!=0){ pmsg_w.type=10;//设置消息类型 len1=strlen(pmsg_w.text); //把消息加到队列中,也就是读取到的文件内容 if((msgsnd(qid,&pmsg_w,len1,IPC_NOWAIT))<0){ perror("msgsnd"); exit(EXIT_FAILURE); } } close(fd); exit(EXIT_SUCCESS); }else{ //接收队列消息,最后一个参数0为阻塞进程,一直等到队列上有消息才进行下一步 len2=msgrcv(qid,&pmsg_r,BUFSIZ,10,0); if(len2>0){ int len=0; pmsg_r.text[len2]='\0'; len=strlen(pmsg_r.text);//求长度 printf("%d\n",len); }else{ perror("msgrcv"); exit(EXIT_FAILURE); } } exit(0); }