// Upon successful completion, pthread_atfork() shall return a value of zero; otherwise, an error number shall be returned to indicate the error.
// @prepare 新进程产生之前被调用
// @parent  新进程产生之后在父进程被调用
// @child    新进程产生之后,在子进程被调用
int pthread_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void));

多进程的多线程程序,听起来多不靠谱。真是闲得淡疼的人才会做此设计。但依旧可以使用万能的推辞:历史造成的。

在 POSIX 标准中,fork 的行为是这样的:复制整个用户空间的数据(通常使用 copy-on-write 的策略,所以可以实现的速度很快)以及所有系统对象,然后仅复制当前线程到子进程。这里:所有父进程中别的线程,到了子进程中都是突然蒸发掉的。

其它线程的突然消失,是一切问题的根源。

我之前从未写过多进程多线程程序,不过公司里有 David Xu 同学(他实现维护着 FreeBSD 的线程库)是这方面的专家,今天跟徐同学讨论了一下午,终于觉得自己搞明白了其中的纠结。嗯,写点东西整理一下思路。

可能产生的最严重的问题是锁的问题。

因为为了性能,大部分系统的锁是实现在用户空间的。所以锁对象会因为 fork 复制到子进程中。

对于锁来说,从 OS 看,每个锁有一个所有者,即最后一次 lock 它的线程。

假设这么一个环境,在 fork 之前,有一个子线程 lock 了某个锁,获得了对锁的所有权。fork 以后,在子进程中,所有的额外线程都人间蒸发了。而锁却被正常复制了,在子进程看来,这个锁没有主人,所以没有任何人可以对它解锁。

当子进程想 lock 这个锁时,不再有任何手段可以解开了。程序发生死锁。

谨慎使用多线程中的fork的更多相关文章

  1. 谨慎使用多线程中的fork 学习!!!!

    前言 在单核时代,大家所编写的程序都是单进程/单线程程序.随着计算机硬件技术的发展,进入了多核时代后,为了降低响应时间,重复充分利用多核cpu的资源,使用多进程编程的手段逐渐被人们接受和掌握.然而因为 ...

  2. 多线程中fork与mutex

    在多线程程序中fork出一个新进程,发现新的进程无法正常工作.因为:在使用fork时会将原来进程中的所有内存数据复制一份保存在子进程中.但是在拷贝的时候,但是线程是无法被拷贝的.如果在原来线程中加了锁 ...

  3. Java多线程中易混淆的概念

    概述 最近在看<ThinKing In Java>,看到多线程章节时觉得有一些概念比较容易混淆有必要总结一下,虽然都不是新的东西,不过还是蛮重要,很基本的,在开发或阅读源码中经常会遇到,在 ...

  4. Java 多线程中的任务分解机制-ForkJoinPool,以及CompletableFuture

    ForkJoinPool的优势在于,可以充分利用多cpu,多核cpu的优势,把一个任务拆分成多个“小任务”,把多个“小任务”放到多个处理器核心上并行执行:当多个“小任务”执行完成之后,再将这些执行结果 ...

  5. 第10章 线程控制(5)_多线程下的fork

    6. 线程和fork 6.1 多线程下的fork (1)历史包袱 ①fork与多线程的协作性很差,这是POSIX系统操作系统的历史包袱. ②长期以来程序都是单线程的,fork运行正常,但引入线程这后, ...

  6. JAVA中的Fork/Join框架

    看了下Java Tutorials中的fork/join章节,整理下. 什么是fork/join框架 fork/join框架是ExecutorService接口的一个实现,可以帮助开发人员充分利用多核 ...

  7. c#初学-多线程中lock用法的经典实例

    本文转载自:http://www.cnblogs.com/promise-7/articles/2354077.html 一.Lock定义     lock 关键字可以用来确保代码块完成运行,而不会被 ...

  8. iOS多线程中,队列和执行的排列组合结果分析

    本文是对以往学习的多线程中知识点的一个整理. 多线程中的队列有:串行队列,并发队列,全局队列,主队列. 执行的方法有:同步执行和异步执行.那么两两一组合会有哪些注意事项呢? 如果不是在董铂然博客园看到 ...

  9. 解决DataGridView在多线程中无法显示滚动条的问题

    在多线程中对DataGridView指定 DataSource 来填充数据,更新数据的时候,会导致DataGridView出现假死,显示错误或者滚动条无法显示的问题,在保证了DataGridView的 ...

随机推荐

  1. iOS 两种易混淆的存储路径

    一,NSBundle 1>我们可以通过解压等操作获取 NSBundle 中的内容. 2>NSBundle主要是包路径,也就是代码编译后的 imge 和 sb 资源文件... 3>例如 ...

  2. 基于FSIOT_A 实验平台SAM3S4B cortex-M3的温湿度采集

    作者:卢老师,华清远见嵌入式学院讲师. DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器.它应用专用的数字模块采集技术和温湿度传感器技术,确保产品具有极高的可靠性与卓越的长期稳 ...

  3. Java_cookie 和session 的区别详解

    这些都是基础知识,不过有必要做深入了解.先简单介绍一下. 二者的定义: 当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择, 都纪 ...

  4. css限制div字符超出部分,简单有方便

    text-overflow: -o-ellipsis-lastline;overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-w ...

  5. 字符串格式化命令 sprintf

    原型 int sprintf( char *buffer, const char *format, [ argument] … ); 参数列表 buffer:char型指针,指向将要写入的字符串的缓冲 ...

  6. BizTalk动手实验(九)业务规则引擎使用

    1 课程简介 通过本课程熟悉业务规则引擎(BRE)的使用(本环境为Windows 2008 32位操作系统环境 + Visual Studio 2010 + BizTalk 210) 2 准备工作 1 ...

  7. mvc 扩展htmlhelper

    using System.Web.Mvc; namespace System.Web.Mvc{    public static class HtmlExtend    {        public ...

  8. HTML问题集锦及笔记

    1.<html>和<body>之间的输出? 加入<p>or<script>均可正常运行 2.<br />换行,用<br>< ...

  9. 代理传值Delegate

    代理方法中加入参数:[delegate passMeToOther:(id)self]:把自己传给别人.

  10. zepto源码--核心方法5(文本操作)--学习笔记

    涉及到文本内容的主要有三个函数:html, text, val. 我们已经见过多次,一个函数多种用途的情况,今天这三个函数也不例外,既可以获取内容,也可以设置内容.判断条件就是有没有传入参数,如果没有 ...