二十二、Linux 进程与信号---进程创建(续)
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 进程与信号---进程创建(续)的更多相关文章
- Linux学习之CentOS(二十六)--Linux磁盘管理:LVM逻辑卷的创建及使用
在上一篇随笔里面 Linux学习之CentOS(二十五)--Linux磁盘管理:LVM逻辑卷基本概念及LVM的工作原理,详细的讲解了Linux的动态磁盘管理LVM逻辑卷的基本概念以及LVM的工作原理, ...
- JAVA基础知识总结:一到二十二全部总结
>一: 一.软件开发的常识 1.什么是软件? 一系列按照特定顺序组织起来的计算机数据或者指令 常见的软件: 系统软件:Windows\Mac OS \Linux 应用软件:QQ,一系列的播放器( ...
- 智课雅思词汇---二十二、-al即是名词性后缀又是形容词后缀
智课雅思词汇---二十二.-al即是名词性后缀又是形容词后缀 一.总结 一句话总结: 后缀:-al ②[名词后缀] 1.构成抽象名词,表示行为.状况.事情 refusal 拒绝 proposal 提议 ...
- [分享] IT天空的二十二条军规
Una 发表于 2014-9-19 20:25:06 https://www.itsk.com/thread-335975-1-1.html IT天空的二十二条军规 第一条.你不是什么都会,也不是什么 ...
- Bootstrap <基础二十二>超大屏幕(Jumbotron)
Bootstrap 支持的另一个特性,超大屏幕(Jumbotron).顾名思义该组件可以增加标题的大小,并为登陆页面内容添加更多的外边距(margin).使用超大屏幕(Jumbotron)的步骤如下: ...
- Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十二】
<Web 前端开发精华文章推荐>2014年第一期(总第二十二期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML ...
- 二十二、OGNL的一些其他操作
二十二.OGNL的一些其他操作 投影 ?判断满足条件 动作类代码: ^ $ public class Demo2Action extends ActionSupport { public ...
- WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]
原文:WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇] 在[上篇]中,我们分别站在消息交换和编程的角度介绍了SOAP Fault和FaultException异常.在服务执行过 ...
- VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池
VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池 在上一节我们创建了完整克隆的自动专有桌面池,在创建过程比较缓慢,这次我们将学习创建Vi ...
- Bootstrap入门(二十二)组件16:列表组
Bootstrap入门(二十二)组件16:列表组 列表组是灵活又强大的组件,不仅能用于显示一组简单的元素,还能用于复杂的定制的内容. 1.默认样式列表组 2.加入徽章 3.链接 4.禁用的列表组 5. ...
随机推荐
- apache ArrayUtils 工具类
org.apache.commons.lang3.ArrayUtils // 1.add():将给定的数据添加到指定的数组中,返回一个新的数组. int[] arr = { 1, 2, 3 }; in ...
- WinterAndSnowmen
https://vjudge.net/problem/TopCoder-12891 暴力想法是:dp[i][s1][s2]前i个,第一个集合xor是s1,第二个集合xor是s2方案数O(n^3) 有x ...
- 遍历HTML DOM 树
<!-- NodeIterator --> <!DOCTYPE html> <html> <head> <meta charset="u ...
- 【css技能提升】完美的 Sticky Footer 布局
在总结之前所做的项目时,遇到过下面这种情况. 在主体内容不足够多或者未完全加载出来之前,就会导致出现左边的这种情况,原因是因为没有足够的垂直空间使得页脚推到浏览器窗口最底部.但是,我们期望的效果是页脚 ...
- 修改 iis 的端口号: 80 与 443
来自:https://support.microsoft.com/en-us/help/149605/how-to-change-the-tcp-port-for-iis-services Micro ...
- 第二十四篇-用VideoView制作一个简单的视频播放器
使用VideoView播放视频,视频路径有三种: 1. SD卡中 2. Android的资源文件中 3. 网络视频 第一种,SD卡中的方法. 路径写绝对路径,如果不能播放,可以赋予读取权限. 效果图: ...
- django框架中的全文检索Haystack
1.什么是Haystack Haystack是django的开源全文搜索框架(全文检索不同于特定字段的模糊查询,使用全文检索的效率更高 ),该框架支持Solr,Elasticsearch,Whoosh ...
- 第十四节、FAST角点检测(附源码)
在前面我们已经陆续介绍了许多特征检测算子,我们可以根据图像局部的自相关函数求得Harris角点,后面又提到了两种十分优秀的特征点以及他们的描述方法SIFT特征和SURF特征.SURF特征是为了提高运算 ...
- HDU 1560 DNA sequence (迭代加深搜索)
The twenty-first century is a biology-technology developing century. We know that a gene is made of ...
- php 在服务器端开启错误日志记录方法
修改php.ini设置,或者通过方法 ini_set设置以下项即可 1.打开error_reporting设置: 如 error_reporting= E_ALL 2. log_errors=On ...