作业
使用进程和文件IO编写以下程序:
//父进程从stdin读取数据到文件
//子进程从该文件读取数据到stdout
//父进程接收到quit就停止
//子进程利用usleep(200)休眠200us
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
#include<time.h>
//父进程从stdin读取数据到文件03test.txt
//子进程从03test.txt读取数据到stdout
//父进程接收到quit就停止
//子进程利用usleep(200)休眠200us
void read_stdin(int fd)
{
char buf[128];
void * p;
//父进程中将stdin中的内容拷贝到文件
int begintime,endtime;
while(1)
{
begintime = clock();
memset(buf, 0, sizeof(buf));
// printf("parent process while\n");
p = fgets(buf, sizeof(buf), stdin);
// printf("p = %p\n", p);
//用户输入quit,退出循环
if(strncmp("quit", buf, 4) == 0)
{
// printf("parent process b\n");
return;
}//读取到结尾
else if(NULL == p)
{
// printf("parent process c\n");
continue;
}
else//输出到文件
{
// printf("parent process w\n");
int n = write(fd, buf, sizeof(buf));
lseek(fd, -n, SEEK_CUR);//定位到这一次写的开头,因为子进程在反复读取,改变了cursor,下一次写入不是从头写,而是向文件结尾写
// lseek(fd, 0, SEEK_SET); //这种会将光标移动到文件头,而由于子进程在同时读取,子进程会从头开始输出,父进程会向文件结尾写
// printf("cursor set\n");
}
endtime = clock();
printf("one loop of input takes:%dms\n", endtime-begintime);
}
}
void write_stdout(int fd)
{
//子进程中将文件中的内容拷贝到stdout
int n = 0;
char buf[128];
int begintime,endtime;
// sleep(3);
// printf("child process entered\n");
while(1)
{
begintime = clock();
// printf("child process while\n");
usleep(200);
memset(buf, 0, sizeof(buf));
n = read(fd, buf, sizeof(buf));//因为存在\0后面还有字符的情况,此处读取的字符串的长度>=输出字符串的长度
//读取到结尾
if(0 == n)
{
continue;
}//正常读取
else if(n > 0)
{
printf("Read %lu bytes:", strlen(buf));
printf("%s", buf); //这里将读取到的字符串从'\0'处截断输出,即输出到\0就不再输出了,注意:包含输入的\n
}
else
{
perror("read");
return;
}
endtime = clock();
printf("one loop of output takes:%dms\n", endtime-begintime);
}
}
int main(int argc, char const *argv[])
{
//打开文件
int fd = open("04stdinCopy", O_RDWR | O_CREAT | O_TRUNC, 0666);
if(fd<0)
{
perror("open");
return -1;
}
printf("open success fd = %d\n", fd);
//创建子进程
pid_t cpid = fork();
//父进程
if(cpid>0)
{
printf("parent process entered\n");
read_stdin(fd);
}//子进程
else if(0 == cpid)
{
printf("child process entered\n");
write_stdout(fd);
}
else{
perror("fork");
return -1;
}
close(fd);
return 0;
}
总结
注意父子进程是依据时间片运行的,并发,所以需要注意读和写时的光标的位置
一遍循环消耗20ms左右时间