zoukankan      html  css  js  c++  java
  • 谨慎使用多线程中的fork

    // 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 这个锁时,不再有任何手段可以解开了。程序发生死锁。

  • 相关阅读:
    《精通情绪》读书笔记
    绩效评估与绩效反馈
    数据分析报告格式zz
    学会谈判zz
    javascript中的双向绑定
    理解 DocumentFragment
    理解Object.defineProperty()
    Vue 改变数组中对象的属性不重新渲染View的解决方案
    ES6中Object.assign() 方法
    控制input输入框光标的位置
  • 原文地址:https://www.cnblogs.com/c-slmax/p/5544766.html
Copyright © 2011-2022 走看看