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

  • 相关阅读:
    记下mongoose(转载)
    vue vue-cli中引入全局less变量的方式
    单标签不支持 伪元素
    删除tppabs,href="javascript:if(confirm)...",、/*tpa=http://...
    系统字体放大导致rem布局错乱,解决方案,已通过测试
    IE条件注释
    hbase部署经验与坑总结
    ubuntu安装mysql 5.7
    静态代理和动态代理
    单例模式
  • 原文地址:https://www.cnblogs.com/c-slmax/p/5544766.html
Copyright © 2011-2022 走看看