Linux fork操作之后发生了什么?又会共享什么呢?
今天我在阅读《Unix网络编程》时候遇到一个问题:accept返回时的connfd,是父子进程之间共享的?我当时很不理解,难道打开的文件描述符不是应该在父子进程间相互独立的吗?为什么是共享的呢?fork之后父子进程之间共享了什么?堆上的变量是否也共享了呢?
做了如下的代码测试,在fork之前先创建一个文件,在子进程中写入字符串“shenlei”,父进程读取文件内容,发现也是“shenlei”。说明打开的文件描述符在父子进程之间是共享的。另一方面,在父子进程中读取文件描述符fd,发现二者相等,进一步证实了这个观点。
看来在《Unix网络编程》中说的是对的,当close一个文件描述符时候会将文件描述符的引用计数-1。在普通文件io操作时,只有当引用计数为0才能真正关闭该文件描述符;在socket操作时,也只有当引用计数为0时才会发送FIN,四次挥手关闭相应的socket。
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <iostream> using namespace std;
static int global_val = 0;
int main()
{
int *p = (int*)malloc(sizeof(int));
*p=0;
int m = 2;
pid_t pid ;
int fd = open("mytest", O_RDWR | O_CREAT, 0666);
if ((pid = fork()) < 0)
{
cout << "fork error" << endl;
}
else {
if (pid == 0)
{
char buf[20]="\0";
int res = read(fd,buf,20);
cout<<"pid is "<<getpid()<<" res is "<<res<<" fd is "<<fd<<" buf is "<< buf<<endl;
close(fd);
//sleep(1);
char bufs[8]="shenlei";
lseek(fd, 0, SEEK_SET);
write(fd,bufs,strlen(bufs));
global_val++;
m++;
(*p)++;
}
else{
sleep(1);
char buf[20]="\0";
lseek(fd, 0, SEEK_SET);
int res = read(fd,buf,20);
cout<<"pid is "<<getpid()<<" res is "<<res<<" fd is "<<fd<<" buf is "<< buf<<endl;
cout << *p << " " << m << " " << global_val<< endl;
}
}
return 0;
}
然后又测试了下,一个进程中的堆对象能否共享,如上述代码所示,结论是不可以的。全局变量,静态变量,全局静态变量也都是不行的。说明在fork创建多进程之后堆栈信息会完全复制给子进程内存空间,父子进程相互独立。
某公司笔试题:当父进程调用fork()创建子进程之后,下列哪些变量在子进程中修改之后,父进程里也会相应地作出改动?
A.全局变量
B.局部变量
C.静态变量
D.文件指针
看懂了以上的分析就很简单了,答案是D。
Linux fork操作之后发生了什么?又会共享什么呢?的更多相关文章
- linux fork进程请谨慎多个进程/线程共享一个 socket连接,会出现多个进程响应串联的情况。
昨天组内同学在使用php父子进程模式的时候遇到了一个比较诡异的问题 简单说来就是:因为fork,父子进程共享了一个redis连接.然后父子进程在发送了各自的redis请求分别获取到了对方的响应体. 复 ...
- Python垃圾回收和Linux Fork
前言 在口袋助理看到了其他部门的同事针对Python2内存占用做的一点优化工作,自己比较感兴趣,遂记录下. Linux fork简介 fork是Linux提供的创建子进程的系统调用.为了优化创建进程速 ...
- Linux进程操作信息
Linux进程操作简单小结 linux上进程有5种状态: 1. 运行(正在运行或在运行队列中等待) 2. 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号) 3. 不可中断(收到信号不唤醒和不 ...
- Linux权限操作 [转]
Linux权限操作 本文内容来自<鸟哥linux私房菜>读后个人做的笔记,该书实为学习linux的很好入门教材 一.文件属性 ls ls -al列出所有的档案属性 ls是List的意思 档 ...
- Linux 意外操作后如何进行数据抢救
Linux 意外操作后如何进行数据抢救 在 GUI 中使用 shift + delete 组合键或是 CLI 下使用 rm -rf 删除选项,这个文件并没有从硬盘(或是其它存储设备)上彻底销毁.当 ...
- linux文本操作界面 vi面板如何复制一行
linux文本操作界面 vi面板如何复制一行 1)把光标移动到要复制的行上2)按yy3)把光标移动到要复制的位置4)按p 在vi里如何复制一行中间的几个字符?如果你要从光标处开始复制 4 个字符,则先 ...
- linux常用操作指令
Linux常用操作指令: 常用指令 ls 显示文件或目录 -l 列出文件详细信息l(list) -a 列出当前目录下所有文件及目录,包括隐藏的a(a ...
- Linux 下操作GPIO(两种方法,驱动和mmap)(转载)
目前我所知道的在Linux下操作GPIO有两种方法: 1.编写驱动,这当然要熟悉Linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据io ...
- Linux 下操作gpio(两种方法,驱动和mmap)
目前我所知道的在linux下操作GPIO有两种方法: 1. 编写驱动,这当然要熟悉linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据 ...
随机推荐
- 使用sqlhelper的简单增删改查
一:所说的简单的三层构架,就是说没有业务逻辑层,将各层没有放到单独的项目中,解决方案如下: 二:form1.cs的详细代码 using System; using System.Collections ...
- [PHP] 跳转以及回到原来的地址
回到原来的地址: 1.PHP(PHP代码) Header('Location:'.$_SERVER["HTTP_REFERER"]); 2.JavaScript(相当于后退按钮,- ...
- Unity3d 基于物理渲染Physically-Based Rendering之最终篇
前情提要: 讲求基本算法 Unity3d 基于物理渲染Physically-Based Rendering之specular BRDF plus篇 Unity3d 基于物理渲染Physically-B ...
- 数据结构与算法分析——C语言描述
P1.1 选择问题,选择出第K大的数,并画出N为不同值的运行时间,K=N/2 毕业两年半,重写排序,感觉良好.代码使用冒泡排序,库函数clock计算大致运行时间. // P1_1.cpp : Defi ...
- vijosP1071 新年趣事之打牌
vijosP1071 新年趣事之打牌 链接:https://vijos.org/p/1071 [思路] 01背包+路径输出. 用d[][]记录[][]可转移的数目,>=2则输出-1,0输出0,否 ...
- [转]让程序在崩溃时体面的退出之Unhandled Exception
原文地址:http://blog.csdn.net/starlee/article/details/6613424 程序是由代码编译出来的,而代码是由人写的.人非圣贤,孰能无过.所以由人写的代码有缺陷 ...
- 《算法问题实战策略》——chaper9——动态规划法技巧
Q1: 数字游戏: 两个人(A.B)用n个整数排成的一排棋盘玩游戏,游戏从A开始,每个人有如下操作: (1) 拿走棋盘最右侧或者最左侧的棋子,被拿走的数字从棋盘中抹掉. (2) 棋盘中还剩 ...
- redis ins 调试
Redis简介: Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工 ...
- Inheritance - SGU 129(线段与多边形相交的长度)
题目大意:给一个凸多边形(点不是按顺序给的),然后计算给出的线段在这个凸多边形里面的长度,如果在边界不计算. 分析:WA2..WA3...WA4..WA11...WA的无话可说,总之细节一定考虑清楚, ...
- poj 1064 Cable master【浮点型二分查找】
Cable master Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 29554 Accepted: 6247 Des ...