#include "sys/types.h" #include "sys/file.h" #include "unistd.h" char r_buf[4]; char w_buf[4]; int pipe_fd[2]; pid_t pid1,pid2,pid3,pid4; int producer(int id); int consumer(int id); int main(int argc,char **argv) { if(pipe(pipe_fd)<0) { printf("pipe create error\n"); exit(-1); } else { printf("pipe is created successfully!\n"); if((pid1=fork())==0) producer(1); if((pid2=fork())==0) producer(2); if((pid3=fork())==0) consumer(1); if((pid4=fork())==0) consumer(2); } close(pipe_fd[0]); close(pipe_fd[1]); int i,pid,status; for(i=0;i<4;i++) pid=wait(&status); exit(0); } int producer(int id) { printf("producer%d is running!\n",id); close(pipe_fd[0]); int i=0; for(i=1;i<10;i++) { sleep(3); if(id==1) strcpy(w_buf,"aaa\0"); else strcpy(w_buf,"bbb\0"); if(write(pipe_fd[1],w_buf,4)==-1) printf("write to pipe erroe\n"); } close(pipe_fd[1]); printf("producer%d is over!\n",id); exit(id); } int consumer(int id) { close(pipe_fd[1]); printf("producer%d is running!\n",id); if(id==1) strcpy(w_buf,"ccc\0"); else strcpy(w_buf,"ddd\0"); while(1) { sleep(1); strcpy(r_buf,"eee\0"); if(read(pipe_fd[0],r_buf,4)==0) break; printf("consumer%d get %s,while the w_buf is %s \n",id,r_buf,w_buf); } close(pipe_fd[0]); printf("consumer%d is over!\n",id); exit(id); } 看以上代码,回答以下问题1. 参考代码main中两个close (pipe_ fd[0]) 和close(pipe. fd[1]) 的作用: 3.参考代码中for(i=0;i<4;i++) pid=wait (&ststus) ; 的作用,如果没有会是何种结果,为什么? 3.参考代码producer ()和consumer ()中的sleep的作用:
时间: 2024-01-05 18:05:16 浏览: 59
1. 参考代码中的两个 close(pipe_fd[0]) 和 close(pipe_fd[1]) 的作用是关闭管道的读和写端,以便后续的 wait 函数能够正确结束进程。
2. 参考代码中的 for(i=0;i<4;i++) pid=wait(&status); 的作用是等待所有子进程结束并回收资源,如果没有等待子进程结束,则会导致子进程变成僵尸进程,浪费系统资源。
3. 参考代码中的 sleep 的作用是为了模拟生产者和消费者的实际操作,让进程在一定的时间间隔内进行操作,以便更好地观察程序的运行情况。
相关问题
例 2:命名管道通信实例 分别编写读写进程的程序 write.c 和 read.c,两个程序之一在当前目录下创建一个 命名管道“mypipe”,然后 write 向管道写数据,read 从管道读数据,两个进程可 任意顺序运行。 编写 write.c: //write.c #include<stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <error.h> #include <fcntl.h> #include <unistd.h> #define N 256 int main(){ char buf[N]; int fd= open("./mypipe",O_WRONLY|O_CREAT,0666); if(fd!=-1) { printf("FIFO file is opened\n"); } else { perror("open failed"); exit(0); } printf("please input string\n"); scanf("%s",buf); getchar(); if ( write(fd,buf,sizeof(buf))!=-1 ) printf("write successful\n"); else perror("write failed:"); exit(EXIT_SUCCESS); } 编写 read.c: //read.c #include<stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <error.h> #include <fcntl.h> #include <unistd.h> #define N 256 int main(){ int fd= open("./mypipe",O_RDONLY|O_CREAT,0666); char buf[N]; if(fd!=-1) { printf("FIFO file is opened\n"); } else { perror("open failed"); exit(0); } if ( read(fd,buf,N )!=-1 ) printf("I received data %s\n",buf); else perror("read error:"); exit(EXIT_SUCCESS); } 运行方式:打开 2 个终端,分别运行读写进程。 请完成以下练习与回答问题: 练习 1:改写本例,使得写进程可以不断的向管道文件写,读进程可以不断的读, 思考如何控制读写顺序。 练习 2:本例中用于管道通信的是一个普通文件,请用 mkfifo 命令或 mkfifo( )函 数创建一个标准管道文件改写本例,查看一下通过管道文件不断读写有什么不同? 问题 1:请说明匿名管道与命名管道在创建方式上有何不同?为什么说匿名管道 只能用于有亲缘关系的进程间进行通信?
练习 1:
可以在写进程和读进程中都用 while 循环,不断地读写数据。为了控制读写顺序,可以在读进程中使用 sleep() 函数来暂停一段时间,等待写进程写入数据。
练习 2:
可以使用 mkfifo() 函数创建一个标准管道文件,具体操作可以参考以下代码:
```c
mkfifo("mypipe", 0666);
```
使用标准管道文件和命名管道文件进行通信的方式是一样的,不同的只是创建方式。通过标准管道文件进行通信时,需要先手动创建管道文件,而命名管道则可以在程序中动态创建。
问题 1:
匿名管道和命名管道在创建方式上的不同在于,匿名管道需要通过 pipe() 函数创建,而命名管道需要通过 mkfifo() 函数创建。
匿名管道只能用于有亲缘关系的进程间进行通信,因为它只能在创建它的进程及其子进程之间使用。而命名管道则可以被多个进程共享使用,因为它是通过文件系统中的文件来实现的。
/* madplay.c */ #include<stdlib.h> #include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include <sys/ioctl.h> #include<fcntl.h> #include<unistd.h> #include<linux/soundcard.h> #define MAXLINE 4096 #define SIZE 16 /* 量化位数 */ #define CHANNELS 1 /* 声道数目 */ #define rate 8000 void madplay(FILE *de_fp) { int fd = open("/dev/dsp", O_WRONLY); if (fd==-1) { perror("open of /dev/dsp failed"); exit(1); } int arg; int status; /* 设置采样时的量化位数 */ arg = SIZE; status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg); if (status == -1) perror("SOUND_PCM_WRITE_BITS ioctl failed"); if (arg != SIZE) perror("unable to set sample size"); /* 设置采样时的声道数目 */ arg = CHANNELS; status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg); if (status == -1) perror("SOUND_PCM_WRITE_CHANNELS ioctl failed"); if (arg != CHANNELS) perror("unable to set number of channels"); /* 设置采样时的采样频率 */ arg = rate; status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg); if (status == -1) perror("SOUND_PCM_WRITE_WRITE ioctl failed"); unsigned char buf[MAXLINE]; printf("open of soundcard success\n");//test while(!feof(de_fp)){ printf("madplaying\n"); int status=fread(buf,sizeof(unsigned char),MAXLINE,de_fp);//de_fp文件数据读入buf if(status==0){ printf("status==0\n"); } else if (status != MAXLINE) perror("read wrong number of bytes"); write(fd,buf,status);//buf数据写入声卡 } close(fd); }优化代码
madplay.c 是一个程序文件的名称,它是一个用于播放MP3格式音频文件的开源软件。madplay.c 的实现基于mad音频解码器库,可以在 Linux、Unix、Windows 等操作系统中使用。其主要功能包括解码和播放 MP3 文件,支持循环、随机播放等操作。
阅读全文