进程互斥和fork
自父进程继承
- 进程的资格(真实(real)/有效(effective)/已保存(saved) 用户号(UIDs)和组号(GIDs))
- 环境(environment)
- 堆栈
- 内存
- 打开文件的描述符(注意对应的文件的位置也是和文件一起由父子进程共享的)
- 执行时关闭(close-on-exec) 标志 (译者注:close-on-exec标志可通过fnctl()对文件描 述符设置,POSIX.1要求所有目录流都必须在exec函数调用时关闭。更详细说明, 参见《UNIX环境高级编程》 W. R. Stevens, 1993, 尤晋元等译(以下简称《高级编程》), 3.13节和8.9节)
- 信号(signal)控制设定
- 信号量(semaphore)
- nice值 (译者注:nice值由nice函数设定,该值表示进程的优先级, 数值越小,优先级越高)
- 进程调度类别(scheduler class) (译者注:进程调度类别指进程在系统中被调度时所属的类别,不同类别有不同优先级,根据进程调度类别和nice值,进程调度程序可计算出每个进程的全局优先级(Global process prority),优先级高的进程优先执行)
- 进程组号
- 对话期ID(Session ID) (《高级编程》:进程所属的对话期 (session)ID, 一个对话期包括一个或多个进程组, 更详细说明参见《高级编程》 9.5节)
- 当前工作目录
- 根目录 (根目录不一定是操作系统的“/”,它可由chroot函数改变)
- 文件方式创建屏蔽字(file mode creation mask (umask)) (《高级编程》:创建新文件的缺省屏蔽字)
- 资源限制
- 控制终端
- 所有互斥锁、读写锁和条件变量(同事考虑到多线程环境)
子进程所独有
- 进程号
- 不同的父进程号(译者注: 即子进程的父进程号与父进程的父进程号不同, 父进程号可由getppid函数得到)
- 自己的文件描述符和目录流的拷贝(译者注: 目录流由opendir函数创建,因其为顺序读取,顾称“目录流”)
- 子进程不继承父进程的进程,正文(text), 数据和其它锁定内存(memory locks) (译者注:锁定内存指被锁定的虚拟内存页,锁定后, 不允许内核将其在必要时换出(page out), 详细说明参见《The GNU C Library Reference Manual》 2.2版, 1999, 3.4.2节)
- 在tms结构中的系统时间(译者注:tms结构可由times函数获得, 它保存四个数据用于记录进程使用中央处理器 (CPU:Central Processing Unit)的时间,包括:用户时间,系统时间, 用户各子进程合计时间,系统各子进程合计时间)
- 资源使用(resource utilizations)设定为0
- 阻塞信号集初始化为空集(译者注:原文此处不明确, 译文根据fork函数手册页稍做修改)
- 不继承由timer_create函数创建的计时器
- 不继承异步输入和输出
- 文件锁不继承,具体原因见参考文献。
随想杂谈
- 假设fork是在父进程有多个线程时发生的,要考虑如下问题:
子进程通过继承整个地址空间的副本,从而父进程哪里继承了所有互斥量,读写锁和条件状态。如果父进程包含多个线程,子进程在 fork 返回以后,如果紧接着不是马上调用 exec 的话,就需要清理锁状态。 在子进程内部只存在一个线程,它是由父进程调用 fork 返回以后,如果父进程中的线程占有锁,子进程同样占有这些锁,问题就出在子进程同样占有这些锁——但子进程不包含这些占有锁的线程副本,所以子进程没有办法知道它占有的那些锁并且需要释放哪些锁。如果子进程从 fork 返回以后马上调用某个 exec 函数,就可以避免这样的问题。这种情况下,老的地址空间被丢弃,所以锁的状态无关紧要。
当然,不用exec,也可以使用pthread_atfork,在调用fork之前,线程先获取进程中所有锁,在调用fork后分别在父子进程中释放这些锁,从而父子可以重新获取和释放这些锁资源。
- pthread接口也提供了进程范围的共享互斥量,这是需要设置互斥类型为PTHREAD_PROCESS_SHARED,因为是进程间共享,要求mutex init时候,使用共享的内存区域中分配的互斥量。进程间互斥,还推荐阅读《nginx模块开发与结构解析》最后一章关于互斥锁的实现方案,一种是基于文件锁,一种是基于原子(本质和互斥同质)操作&信号量。建议集合accept_mutex锁的实现了解不同互斥锁的原理!
记录锁的继承和释放
1、锁与进程和文件两方面
a、当一个进程终止时,它所建立的锁全部释放;(即 进程退出,文件锁自动释放)
b、任何时候关闭一个描述符时,则该进程通过这一描述符可以引用的文件上的任何一把锁都释放。(即 关闭文件,文件锁自动释放)情况一::
fd1 = open(pathname,....);
read_lock(fd1,....);
fd2 = dup(fd1);
close(fd2); //此时,在close(fd2)后,在fd1上加的锁被释放。
情况二::
fd1 = open(pathname,....);
read_lock(fd1,....);
fd2 = open(pathname,...);
close(fd2); //此时,在close(fd2)后,在fd1上加的锁被释放。2、由fork产生的子进程不继承父进程所设置的锁。(文件锁不能被继承)
这意味着,若一个进程得到一把锁,然后调用fork,那么对于父进程获得的锁而言,子进程被视为另外一个进程,对于从父进程处继承过来的任一描述符,子进程需要调用fcntl才能获得它自己的锁。
(这其实也是锁的本意,文件锁的作用是阻止多个进程同时写一个文件或区域,如果子进程继承父进程的锁,则父、子就可以同时写同一个文件。这显然是不对的。)3、在执行exec后,新程序可以继承原执行程序的锁。(EXEC文件锁被继承)
执行exec后,其实是用当前进程的进程实体替换原进程的进程实体。原进程被杀掉(但保留了 进程ID即 PID)
进程互斥和fork的更多相关文章
- 让powershell同时只能运行一个脚本(进程互斥例子)
powershell,mutex,互斥,进程互斥,脚本互斥 powershell脚本互斥例子,在powershell类别文章中,声明原创唯一. powershell 传教士 原创文章 2016-07- ...
- Java使用FileLock实现Java进程互斥锁
原理:JDK的nio包中FileLock实现类似Linux fcntl的文件锁, 可使文件被进程互斥访问. 借助此功能, 可以实现强大的Java进程互斥锁, 从而在应用层面保证同一时间只有惟一的Ja ...
- 进程控制之fork函数
一个现有进程可以调用fork函数创建一个新进程. #include <unistd.h> pid_t fork( void ); 返回值:子进程中返回0,父进程中返回子进程ID,出错返回- ...
- 进程创建函数fork()、vfork() ,以及excel()函数
一.进程的创建步骤以及创建函数的介绍 1.使用fork()或者vfork()函数创建新的进程 2.条用exec函数族修改创建的进程.使用fork()创建出来的进程是当前进程的完全复制,然而我们创建进程 ...
- 进程互斥(锁)------------------>一个坑
进程互斥锁 引入: 进程之间数据不共享,但是共享同一套文件系统(如硬盘.键盘.cpu等),所以访问同一个文件,或同一个打印终端,是没有问题的,竞争带来的结果就是错乱,如何控制,就是加锁处理,即进程加锁 ...
- UNIX环境编程学习笔记(19)——进程管理之fork 函数的深入学习
lienhua342014-10-07 在“进程控制三部曲”中,我们学习到了 fork 是三部曲的第一部,用于创建一个新进程.但是关于 fork 的更深入的一些的东西我们还没有涉及到,例如,fork ...
- linux进程原语之fork()
一.用法解析: fork()这个函数,可以说是名如其人了,众所周知fork这个单词本意为叉子,老外取学术名字的时候总会有一些象形的想法,于是就有了下图~ fork()函数是计算机程序设计中的分叉函数. ...
- 【Linux编程】进程标识符与fork函数
ID为0的进程一般是调度进程.常被称为交换进程(swapper),是内核中的系统进程. ID为1的进程叫做init进程,是一个普通用户进程,不属于内核,由内核调用. 一个现有进程能够调用fork函数创 ...
- [Chapter 3 Process]Practice 3.1 相关知识:进程创建、fork函数
3.1 Using the program shown in the Figure3.30, explain what the output will be at LINE A 答案:LINE A 处 ...
随机推荐
- 调用webapi 错误:使用 HTTP 谓词 POST 向虚拟目录发送了一个请求,而默认文档是不支持 GET 或 HEAD 以外的 HTTP 谓词的静态文件。的解决方案
第一次调用webapi出错如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http:// ...
- JavaScript定时器原理分析
.header { cursor: pointer } p { margin: 3px 6px } th { background: lightblue; width: 20% } table { t ...
- 使用antd UI组件有感
公司使用的的react.js的版本提14.7的,JS版本使用的是ES6语法,因此在使用antd过程中,有些许不愉快的记录,分享给大家,一起学习: 如果是react 14.7版本时,使用getField ...
- hover 变内容
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 关于获取、设置css样式封装的函数入门版
<html> <head> <meta charset="UTF-8"> <title>CSS样式的获取和设置:简单版</ti ...
- unsigned无符号、有符号类型的符号拓展
先看一段代码 #include <stdio.h> main(){ unsigned ; char b = a; printf("%d %d",a,b); ; } a输 ...
- maven的eclise配置
http://blog.csdn.net/guanning0109/article/details/26069277
- onscroll事件,onresize事件
js获取页面元素高度.宽度 网页可见区域宽: document.body.clientWidth; 网页可见区域高: document.body.clientHeight; 网页可见区域宽: do ...
- 第二轮冲刺-Runner站立会议09
今天:将日历界面和主程序结合起来 明天:查看整个项目,调试是否有问题
- 面试题目——《CC150》树与图
面试题4.1:实现一个函数,检查二叉树是否平衡.在这个问题中,平衡树的定义如下:任意一个结点,其两颗子树的高度差不超过1. 思路:两个方法,第一种速度较快 package cc150; public ...