// 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. .net的五层架构

    原文章地址是http://www.360doc.com/content/11/1210/21/19147_171335782.shtml 我们刚开始学习架构的时候,首先会想到分层的概念,分层架构比较经 ...

  2. Maven dependency spring-web vs spring-webmvc

    <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmv ...

  3. linux下获取本机IP

    转载:http://blog.chinaunix.net/uid-20593763-id-1620213.html 源代码级Unix/Linux 通用网卡IP地址获取方法 在Unix和Linux系统下 ...

  4. Point Grey FlyCapture 实例汇总

    Example Language Description AsyncTriggerEx C++ Demonstrates some of the basic asynchronous trigger ...

  5. ubuntu上安装Eclipse时遇到的一个错误

    A Java Runtime Environment (JRE) or Java Development Kit (JDK)must be available in order to run Ecli ...

  6. js 时间格式化 -- 时间加减实现

    时间格式化的方法: Date.prototype.Format = function (fmt) { //author: meizz var o = { "M+": this.ge ...

  7. 链接后加"/"与不加"/"的区别

    1.http://www.abc.com/abc2.http://www.abc.com/abc/ 当Web服务器接收到对某个末尾不含斜杠的url请求时,例如“http://www.abc.com/a ...

  8. 关于格式转换 “%a.bs”

    这个形式的格式转换符用于输出, 如果a <= b,  那么输出的字符串串长大于等于a, 小于b; 否则, 输出的串长按照a指定的输出. (不够,用空格补齐)

  9. 一个xib钟多个Cell

    在实际开发中,有时候需要在一个xib钟拖几个cell,注意连线过程的object选择,不然出现没反应的现象. 例如: 在下图中,我在一个xib钟创建了五个cell,他们分别是:收货地址.订单信息.支付 ...

  10. windows下vim 块模式问题

    VIM: gvim 使用 Ctrl+V 發表於 2005 年 10 月 27 日 由 Tsung vim 要做垂直選取的動作, 就要使用 "Ctrl + v", 但是 gvim 會 ...