代码之家  ›  专栏  ›  技术社区  ›  Douglas Leeder

Solaris进程挂起退出

  •  1
  • Douglas Leeder  · 技术社区  · 15 年前

    在Solaris 9和10(x86和SPARC)上,我们有一个在退出时挂起的进程:

    fe0b5994 lwp_park (0, 0, 0)
    fe0b206c slow_lock (ff388908, fe080400, 0, 0, 98, fe0abe00) + 58
    ff376aa8 __deregister_frame_info_bases (2a518, 1, 0, 2daf0, 0, ff376be4) + 4c
    00014858 ???????? (0, ff000000, 0, 0, 0, 0)
    00019920 _fini    (0, 0, 210fc, fe21cbf0, 5, fe25897c) + 4
    fe21cbf0 _exithandle (fee66a4c, 0, 40, 0, 0, fe2bc000) + 70
    fe2a0564 exit     (0, fdefb47c, 40, fdefb8ff, 2c, 0) + 24
    fee66a4c (our code) (4e280, 5ab5c, 5aa60, 2ed0, 81010100, fdefb988) + 244
    

    我们的代码是使用GCC 3.4.6在Solaris9机器上编译的。

    所讨论的进程是来自多线程父进程的单线程子进程, fork Ed但不是 exec 预计起飞时间。

    有人看到类似的东西吗?

    你知道更新版本的GCC是否能解决这个问题吗?

    2 回复  |  直到 15 年前
        1
  •  2
  •   Kenster marc_s    15 年前

    你可以试着打电话 _exit() 退出子进程,而不是 exit() .exit()是一个库函数,它在退出前执行各种形式的库清理——例如,它将stdio缓冲区刷新到磁盘。_ exit()是终止进程的实际系统调用。即使在单线程程序中,通常也会在分叉的子程序中使用exit(),以防止库清理发生两次。

        2
  •  1
  •   Employed Russian    15 年前

    这就是为什么您应该在mt进程中总是在fork之后执行:您不知道父进程中其他线程持有哪些锁,以及何时需要这些锁之一。在这里,您需要一个在出口处,但您不能得到它,因为锁定它的线程不存在于子线程中。

    GCC的新版本不太可能对您有所帮助。即使它有帮助,也只是时间问题,否则你会撞上这样的锁。

    在创建第一个线程之前使用fork,或者在fork之后立即执行exec。这些确实是唯一明智的选择。