• 谨慎使用多线程中的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 这个锁时,不再有任何手段可以解开了。程序发生死锁。

  • 相关阅读:
    【笔记】进化型开发方法
    错误注入学习笔记
    【C/C++】关于编译错误 "error C2146: syntax error : missing ';' before identifier 'xxx'"
    查找进程加载到内存中的EntryPoint
    devepxress qtp 点击子菜单
    RijndaelManaged 自定义key和iv
    sql server transaction
    使用gzip压缩字符串
    tsql 与时间(周)相关的一些操作
    excel 合并单元格
  • 原文地址:https://www.cnblogs.com/c-slmax/p/5544766.html
Copyright © 2020-2023  润新知