22.2 父子进程操作文件

文件操作由两种模式:

  IO 系统调用操作文件

  标准C IO 操作文件

看代码:

 #include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h> int g_val = ;//全局变量,存放在数据段 int main(void)
{
int a_val = ;//局部变量,调用的时候存放在栈中
static int s_val = ;//静态变量,存放在数据段
printf("pid: %d", getpid()); FILE *fp = fopen("s.txt", "w");
int fd = open("s_fd.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG); char *s = "hello world";
ssize_t size = strlen(s) * sizeof(char); /* fork 之前,为父进程调用 */
fprintf(fp, "s: %s, pid: %d\n", s, getpid());//标准 IO 写入(带缓存),针对文件操作的是全缓存
write(fd, s, size); //内核提供的 IO 系统调用(不带缓存) pid_t pid;
pid = fork();//创建子进程
//在 fork 后,会运行两个进程(父进程和子进程)
if(pid < ) {
perror("fork error");
} else if(pid > ) {
//父进程(在父进程中返回的是子进程的 pid)
//父进程执行的代码
g_val = ;
a_val = ;
s_val = ; printf("I am parent process pid is %d, ppid is %d, fork return is %d\n",
getpid(), getppid(), pid);
printf("g_val: %p, a_val: %p, s_val: %p\n", &g_val, &a_val, &s_val);
} else {
//子进程(在子进程中 fork 返回的是0)
//子进程执行的代码
g_val = ;
a_val = ;
s_val = ;
printf("I am child process pid is %d, ppid is %d, fork return is %d\n",
getpid(), getppid(), pid);
printf("g_val: %p, a_val: %p, s_val: %p\n", &g_val, &a_val, &s_val);
} //这里的代码是父子进程都要执行的代码,写入父子进程各自的缓存当中
fprintf(fp, " pid: %d, g_val: %d, a_val: %d, s_val: %d\n", getpid(), g_val, a_val, s_val);
sleep(); return ;
}

  编译运行后,两个文件都生成了。

  

  父进程文件 s.txt

  

  子进程文件 s_fd.txt

  

  系统调用不经过缓存,执行 write 后就直接写进了文件当中,标准IO是写入缓存了。

  创建的缓存是在堆当中的,我们的代码是在 fork 之前,那么缓存就在父进程的虚拟空间的堆当中,当 fork 之后,子进程会 COPY 一份父进程的堆空间。

  同样 fork 之后也由一份写入缓存的 fprintf,此时是各自写入各自的缓存,在结束的时候父子进程都会清缓存,都会写入 fp 当中

  

22.3 操作文件时的内核结构体变化

  • 子进程只继承父进程的文件描述符表,不继承但共享文件表项和 i-node
  • 父进程创建一个子进程后,文件表项中的引用计数器加1 变成 2,当父进程作 close 操作后,计数器减 1,子进程还是可以使用文件表项(即子进程还是可以操作文件),只有当计数器为 0 时,才会释放文件表项。

  

  运行 fork:

  

  例子:父进程调节文件偏移量,子进程写入

  process_append.c

 #include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int main(int argc, char *argv[])
{
if(argc < )
{
fprintf(stderr, "usage: %s file\n", argv[]);
exit();
} int fd = open(argv[], O_WRONLY);
if(fd < )
{
perror("open error");
exit();
} pid_t pid = fork();
if(pid < )
{
perror("fork error");
exit();
}
else if(pid > )
{//父进程将文件偏移量调整到文件尾部
if(lseek(fd, 0L, SEEK_END) < ) {
perror("lseek error");
exit();
}
}
else
{//子进程从文件尾部追加内容
char *str = "hello child";
ssize_t size = strlen(str) * sizeof(char); sleep();//保证父进程调节偏移量成功 //从用户角度去看,子进程会复制一份父进程的文件描述符,都指向同一个文件
//从内核角度区看,文件描述符表复制了一份,文件描述符表指向了同一个文件表项,都指向同一个文件
//此处的 fd 是从父进程中复制过来的
//但和父进程中的 fd 都是指向同一个文件的
if(write(fd, str, size) != size) {
perror("write error");
exit();
}
} printf("pid ; %d finish\n", getpid());
sleep(); //父子进程都要去关闭文件描述符
close(fd); return ;
}

  编译运行:

  

  

二十二、Linux 进程与信号---进程创建(续)的更多相关文章

  1. Linux学习之CentOS(二十六)--Linux磁盘管理:LVM逻辑卷的创建及使用

    在上一篇随笔里面 Linux学习之CentOS(二十五)--Linux磁盘管理:LVM逻辑卷基本概念及LVM的工作原理,详细的讲解了Linux的动态磁盘管理LVM逻辑卷的基本概念以及LVM的工作原理, ...

  2. JAVA基础知识总结:一到二十二全部总结

    >一: 一.软件开发的常识 1.什么是软件? 一系列按照特定顺序组织起来的计算机数据或者指令 常见的软件: 系统软件:Windows\Mac OS \Linux 应用软件:QQ,一系列的播放器( ...

  3. 智课雅思词汇---二十二、-al即是名词性后缀又是形容词后缀

    智课雅思词汇---二十二.-al即是名词性后缀又是形容词后缀 一.总结 一句话总结: 后缀:-al ②[名词后缀] 1.构成抽象名词,表示行为.状况.事情 refusal 拒绝 proposal 提议 ...

  4. [分享] IT天空的二十二条军规

    Una 发表于 2014-9-19 20:25:06 https://www.itsk.com/thread-335975-1-1.html IT天空的二十二条军规 第一条.你不是什么都会,也不是什么 ...

  5. Bootstrap <基础二十二>超大屏幕(Jumbotron)

    Bootstrap 支持的另一个特性,超大屏幕(Jumbotron).顾名思义该组件可以增加标题的大小,并为登陆页面内容添加更多的外边距(margin).使用超大屏幕(Jumbotron)的步骤如下: ...

  6. Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十二】

    <Web 前端开发精华文章推荐>2014年第一期(总第二十二期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML ...

  7. 二十二、OGNL的一些其他操作

    二十二.OGNL的一些其他操作 投影 ?判断满足条件 动作类代码: ^ $   public class Demo2Action extends ActionSupport {     public ...

  8. WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]

    原文:WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇] 在[上篇]中,我们分别站在消息交换和编程的角度介绍了SOAP Fault和FaultException异常.在服务执行过 ...

  9. VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池

    VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池 在上一节我们创建了完整克隆的自动专有桌面池,在创建过程比较缓慢,这次我们将学习创建Vi ...

  10. Bootstrap入门(二十二)组件16:列表组

    Bootstrap入门(二十二)组件16:列表组 列表组是灵活又强大的组件,不仅能用于显示一组简单的元素,还能用于复杂的定制的内容. 1.默认样式列表组 2.加入徽章 3.链接 4.禁用的列表组 5. ...

随机推荐

  1. 【linux】vim常用操作及vim插件的安装使用

    vim是linux下一个非常好用的文本编辑器,在linux下开发的人员要熟练掌握vim常用命令. 1.  打开在第n行 vim +143 filename.txt 2. 只读模式打开 vim -R / ...

  2. 关于overflow-x: hidden隐藏滚动条失效的解决方案

    在苦逼写页面的时候,发现有种情况overflow-x: hidden失效了,chrome表现完好,qq浏览器有问题,微信上面展示有问题. 微信上面展示是一样能够滑动的. 如果出现类似问题的同学,请试一 ...

  3. 百度地图API:自定义控件

    HTML: <!DOCTYPE html> <html> <head> <meta name="viewport" content=&qu ...

  4. MVC aspx

    客户端服务器---Model(模型)---View(视图)---Control(控制器) 1.ASP.NET  MVC 2.新建项目引擎选aspx.在Controllers创建控制器,默认启动Home ...

  5. python中深拷贝和浅拷贝

    python中所谓浅拷贝就是对引用的拷贝,所谓深拷贝就是对对象的资源的拷贝. 首先,对赋值操作我们要有以下认识: 赋值是将一个对象的地址赋值给一个变量,让变量指向该地址( 旧瓶装旧酒 ). 修改不可变 ...

  6. java 8: ClassNotFoundException: sun.jdbc.odbc.JdbcOdbcDriver

    转眼之间, java 11都快要推出了. 而我一直都在 java 7环境下写代码,真的不想升级,不想改变什么,可世界每天都在变化. 最近因为服务端需要SNI,而 java 7 只支持客户端的SNI,只 ...

  7. CSS文档统筹

    一.CSS文档统筹 1.整站里相同的CSS样式提取到一个样式表里,各个页面调用相同的样式文件即可: 2.网站较大的情况下一般会把网站的头部,尾部单独分离出来,包括样式文件: 1)根据页面类型分离文件 ...

  8. jQuery中mouseleave和mouseout的区别详解

    很多人在使用jQuery实现鼠标悬停效果时,一般都会用到mouseover和mouseout这对事件.而在实现过程中,可能会出现一些不理想的状况. 先看下使用mouseout的效果: <p> ...

  9. FFT笔记

    蝴蝶操作和Rader排序 蝴蝶操作的定义: 雷德(Rader)算法 (Gold Rader bit reversal algorithm) 按自然顺序排列的二进制数,其下面一个数总是比其上面一个数大1 ...

  10. Python之包

    包是一种通过使用'.模块名'来组织python模块名称空间的方式.创建包是为了用文件夹将文件/模块组织起来,创建包的目的不是为了运行,而是为了被导入使用.包的本质就是一个文件,其功能是将文件组织起来, ...