今天我在阅读《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操作之后发生了什么?又会共享什么呢?的更多相关文章

  1. linux fork进程请谨慎多个进程/线程共享一个 socket连接,会出现多个进程响应串联的情况。

    昨天组内同学在使用php父子进程模式的时候遇到了一个比较诡异的问题 简单说来就是:因为fork,父子进程共享了一个redis连接.然后父子进程在发送了各自的redis请求分别获取到了对方的响应体. 复 ...

  2. Python垃圾回收和Linux Fork

    前言 在口袋助理看到了其他部门的同事针对Python2内存占用做的一点优化工作,自己比较感兴趣,遂记录下. Linux fork简介 fork是Linux提供的创建子进程的系统调用.为了优化创建进程速 ...

  3. Linux进程操作信息

    Linux进程操作简单小结 linux上进程有5种状态: 1. 运行(正在运行或在运行队列中等待) 2. 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号) 3. 不可中断(收到信号不唤醒和不 ...

  4. Linux权限操作 [转]

    Linux权限操作 本文内容来自<鸟哥linux私房菜>读后个人做的笔记,该书实为学习linux的很好入门教材 一.文件属性 ls ls -al列出所有的档案属性 ls是List的意思 档 ...

  5. Linux 意外操作后如何进行数据抢救

    Linux 意外操作后如何进行数据抢救 在 GUI 中使用  shift + delete  组合键或是 CLI 下使用 rm -rf 删除选项,这个文件并没有从硬盘(或是其它存储设备)上彻底销毁.当 ...

  6. linux文本操作界面 vi面板如何复制一行

    linux文本操作界面 vi面板如何复制一行 1)把光标移动到要复制的行上2)按yy3)把光标移动到要复制的位置4)按p 在vi里如何复制一行中间的几个字符?如果你要从光标处开始复制 4 个字符,则先 ...

  7. linux常用操作指令

    Linux常用操作指令: 常用指令 ls        显示文件或目录 -l           列出文件详细信息l(list) -a          列出当前目录下所有文件及目录,包括隐藏的a(a ...

  8. Linux 下操作GPIO(两种方法,驱动和mmap)(转载)

    目前我所知道的在Linux下操作GPIO有两种方法: 1.编写驱动,这当然要熟悉Linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据io ...

  9. Linux 下操作gpio(两种方法,驱动和mmap)

    目前我所知道的在linux下操作GPIO有两种方法: 1.  编写驱动,这当然要熟悉linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据 ...

随机推荐

  1. 查看Mysql执行计划

    使用navicat查看mysql执行计划: 打开profile分析工具: 查看是否生效:show variable like ‘%profil%’; 查看进程:show processlist; 选择 ...

  2. nginx -- nginx平台初探(100%)

    初探nginx架构(100%) 众所周知,nginx性能高,而nginx的高性能与其架构是分不开的.那么nginx究竟是怎么样的呢?这一节我们先来初识一下nginx框架吧. nginx在启动后,在un ...

  3. 【转】VMware 11安装Mac OS X 10.10 及安装Mac Vmware Tools.

    原文网址:http://www.cnblogs.com/Anand/p/4483727.html 先上一张效果图兴奋一下,博主穷屌丝一个,只能通过虚拟黑苹果体验下高富帅的生活,感觉超爽的,废话不多说的 ...

  4. MYSQL仅仅向某个字段进行插入

    例子: mysql> show create table student \G . row *************************** Table: student Create T ...

  5. 关于HttpsURLConnection的连接问题

    本地测试好的项目拿到服务器上后,通过SSL连接,将Http改成Https,并指定了服务器的IP,结果连接失败.查了资料后发现,直接指定IP,SSL是无法定位连接的,实际上应该指定服务器端配置好的Hos ...

  6. Hadoop的文件读写操作流程

    以下主要讲解了Hadoop的文件读写操作流程: 读文件 读文件时内部工作机制参看下图: 客户端通过调用FileSystem对象(对应于HDFS文件系统,调用DistributedFileSystem对 ...

  7. Bzoj 2038: [2009国家集训队]小Z的袜子(hose) 莫队,分块,暴力

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 5763  Solved: 2660[Subm ...

  8. XMPP and Asterisk integration

    http://www.mundoopensource.com.br/en_page_xmpp_asterisk_pratical_example/ www.mundoopensource.com.br ...

  9. java ee eclipse 配置 ssh框架

    mvnDebug tomcat:run 这条命令主要用来远程测试,它会监听远程测试用的8000端口,在eclipse里打开远程测试后,它就会跑起来了,设断点,调试,一切都是这么简单. 0.如果是mav ...

  10. 使用Spring-data-redis操作Redis的Sentinel

    介绍 Spring-Data-Redis项目(简称SDR) 是对Redis的Key-Value数据存储操作提供了更高层次的抽象,提供了一个对几种主要的redis的Java客户端(例 如:jedis,j ...