Linux中不带缓冲区的write和带缓冲区的printf/fputs区别,以及Linux中的进程缓冲区拷贝

在Linux中,write是不带缓冲区的函数,也就是其写完以后不会在缓冲区中存储,直接写出。
考虑以下代码

1、使用fputs

# include <unistd.h>
# include <stdio.h>
# include <stdlib.h>
# include <errno.h>
 
int main(void)
{
     FILE *stream;
     if ((stream = fopen ( "./log.txt" , "a" )) == NULL) //打开文件流
     {
         printf( "error: %d\n" , errno);
         exit (1);
     }
     
     char buf[20]="hello world";
     
     fputs ( buf , stream);//带缓冲区的写
 
     sleep(20);
 
     return 0;
}

由于fputs是带缓冲区的写,而文件流默认是全缓冲,那么程序执行结果如下:
在sleep(20)之前:
在这里插入图片描述
可以看到,根本没有数据写入

sleep(20)之后,即程序结束后:
在这里插入图片描述只有程序执行完,全缓冲内容才写入进去。

2、使用write

write是不带缓冲的

# include <unistd.h>
# include <stdio.h>
# include <stdlib.h>
# include <errno.h>
# include <fcntl.h>
# include<string.h>
 
int main(void)
{
     int fd;
     if ((fd = open ( "./log.txt" , O_WRONLY )) == -1) {
     //以只写方式打开文件描述符,
         printf( "error: %d\n" , errno);
         exit (1);
     }
     
     char buf[20]="hello world";
     
     write(fd,buf,strlen(buf));
     //write写的是文件描述符
     //注意:这里用strlen,返回的是11,即字符串长度
     //如果用sizeof(),返回的是20,即数组长度
     //如果是buf[]="hello world",那么用strlen返回的仍然是11,
     //但是用sizeof返回的却是12,因为buf[]会自动在末尾加上'\0',而sizeof会算进去这个'\0',但是strlen却不会
 
     sleep(20);
 
     return 0;
}


执行结果:
sleep之前打开文件
在这里插入图片描述
可以看到,write完立刻就有数据输出

3、Linux的进程缓冲区拷贝

在《Unix环境高级编程第三版》183页有这么一个程序:

#include <unistd.h>
#include <stdio.h>
#include <error.h>
#include <stdlib.h>

int globvar=6;
char buf[]="a write to stdout\n";


int main(int argc,char *argv[])
{
   int var;
   pid_t pid;

   var=88;
   if(write(STDOUT_FILENO,buf,sizeof(buf)-1)!=sizeof(buf)-1)
   {
      return 0;
   }
   printf("before fork\n");
   if((pid=fork())<0)
   {
      printf("fork error\n");
      exit(0);
   }
   else if(pid==0)//zi jin cheng
   {
      globvar++;
      var++;
   }
   else
   {
      sleep(20);//zhu jin cheng
   }

   printf("pid = %ld, glob = %d, var = %d\n",(long)getpid(),globvar,var);

   return 0;
    
}

如果在终端中执行:
在这里插入图片描述
如果执行终端改为文件:

先是(sleep之前):
在这里插入图片描述立即出现write结果,这是因为write无缓冲,立即打印输出,而这个before fork是子线程结束打印出的。

然后(sleep 之后)
在这里插入图片描述可以看到,如果打印到文件,会打印两个“before fork”,第二个是主线程打印出来的。
这是因为printf会打印到缓冲区,而文件缓冲是全缓冲,进程拷贝会把缓冲区也拷贝,在进程结束后打印到文件中去。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值