IO进程线程_Day04

作业

使用进程和文件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左右时间

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值