标签: zombie-process

僵尸存在......在.NET中?

我和队友讨论过锁定.NET.他是一个非常聪明的人,在低级和高级编程方面拥有广泛的背景,但他在低级编程方面的经验远远超过我的.无论如何,他认为,如果可能的话,应该避免在预期会处于重负载的关键系统上进行.NET锁定,以避免"僵尸线程"崩溃系统的可能性很小.我经常使用锁定而且我不知道什么是"僵尸线程",所以我问道.我从他的解释中得到的印象是僵尸线程是一个已经终止但仍然保留在某些资源上的线程.他给出了僵尸线程如何破坏系统的一个例子是一个线程在锁定某个对象后开始一些程序,然后在某个时刻终止锁定才能被释放.这种情况有可能使系统崩溃,因为最终,尝试执行该方法将导致所有线程都在等待访问永远不会返回的对象,因为使用锁定对象的线程已经死亡.

我想我得到了这个的要点,但如果我离开基地,请告诉我.这个概念对我来说很有意义.我并不完全相信这是一个可能在.NET中发生的真实场景.我以前从未听说过"僵尸",但我确实认识到,在较低级别深入工作的程序员往往对计算基础(如线程)有更深入的了解.我肯定看到了锁定的价值,然而,我看到许多世界级程序员利用锁定.我也很有能力为自己评估这个,因为我知道这lock(obj)句话实际上只是语法糖:

bool lockWasTaken = false;
var temp = obj;
try { Monitor.Enter(temp, ref lockWasTaken); { body } }
finally { if (lockWasTaken) Monitor.Exit(temp); }
Run Code Online (Sandbox Code Playgroud)

因为Monitor.Enter并且Monitor.Exit被标记了extern.似乎可以想象.NET会做某种处理来保护线程免受可能产生这种影响的系统组件的影响,但这纯粹是推测性的,可能只是基于我从未听说过"僵尸线程"的事实.之前.所以,我希望我能在这里得到一些反馈:

  1. 是否有一个比我在这里解释的"僵尸线程"更清晰的定义?
  2. 僵尸线程可以在.NET上出现吗?(为什么/为什么不?)
  3. 如果适用,我如何强制在.NET中创建僵尸线程?
  4. 如果适用,如何利用锁定而不会在.NET中冒着僵尸线程的风险?

更新

两年多前我问过这个问题.今天发生这种事:

对象处于僵尸状态.

.net c# multithreading load zombie-process

379
推荐指数
5
解决办法
2万
查看次数

如何杀死僵尸进程

我在前台启动了我的程序(一个守护程序),然后我用它杀了它kill -9,但我得到了一个僵尸,我无法杀死它kill -9.如何杀死僵尸进程?

如果僵尸是一个死的进程(已经被杀死),我如何从输出中删除它ps aux

root@OpenWrt:~# anyprogramd &
root@OpenWrt:~# ps aux | grep anyprogram
 1163 root      2552 S    anyprogramd
 1167 root      2552 S    anyprogramd
 1169 root      2552 S    anyprogramd
 1170 root      2552 S    anyprogramd
10101 root       944 S    grep anyprogram
root@OpenWrt:~# pidof anyprogramd
1170 1169 1167 1163
root@OpenWrt:~# kill -9 1170 1169 1167 1163
root@OpenWrt:~# ps aux |grep anyprogram
 1163 root         0 Z    [cwmpd]
root@OpenWrt:~# kill -9 1163
root@OpenWrt:~# ps aux |grep anyprogram
 1163 …
Run Code Online (Sandbox Code Playgroud)

linux shell ubuntu debian zombie-process

169
推荐指数
5
解决办法
41万
查看次数

确保子程序在退出Python程序时已经死了

有没有办法确保所有创建的子进程在Python程序的退出时间都死了?通过子进程,我指的是使用subprocess.Popen()创建的.

如果没有,我应该迭代所有发出的杀戮然后杀死-9?什么更干净?

python subprocess kill zombie-process

59
推荐指数
7
解决办法
5万
查看次数

Zombie进程vs Orphan进程

当父进程在子进程死后读取其退出状态时不使用等待系统调用时,会创建一个Zombie,并且当原始父进程在子进程终止时,孤立是由init回收的子进程.

在内存管理和进程表方面,这些进程的处理方式有何不同,特别是在UNIX中?

当僵尸或孤儿的创建可能对更大的应用程序或系统有害时,有什么例子或极端情况?

c unix fork zombie-process

52
推荐指数
5
解决办法
5万
查看次数

在UNIX系统上杀死已失效的进程

我的系统上有一个已解散的进程:

abc      22093 19508  0 23:29 pts/4    00:00:00 grep ProcA
abc      31756     1  0 Dec08 ?        00:00:00 [ProcA_my_collect] <defunct>
Run Code Online (Sandbox Code Playgroud)

如何在不重启机器的情况下终止上述过程?我试过了

kill -9 31756
sudo kill -9 31756
Run Code Online (Sandbox Code Playgroud)

unix kill process zombie-process

49
推荐指数
3
解决办法
8万
查看次数

什么是僵尸及其原因?有Zombie进程和Zombie对象吗?

我可以找到关于僵尸的问题,但没有一个直接解决它们是什么以及为什么以及它们如何发生.有几个解决了在回答特定问题但不解决原因的背景下僵尸进程的问题.

还有关于僵尸进程和有关Objective-C/Cocoa相关僵尸对象的问题的问题.有什么区别或这些有何关系?Mac/iPhone上的"EXEC_BAD_ACCESS"(或其他平台上的类似错误)是僵尸的代名词吗?

如何防止僵尸,是否有任何有助于避免僵尸的最佳做法?

将这些信息放在一个地方会很有帮助.如果可能,此问题旨在与平台/语言无关.

zombie-process

35
推荐指数
2
解决办法
1万
查看次数

wait3(waitpid别名)返回-1,并且errno设置为ECHILD时不应该

上下文就是这个Redis问题.我们有一个wait3()等待AOF重写子项在磁盘上创建新AOF版本的调用.当孩子完成后,通知父母wait3()以便用新的AOF替换旧的AOF.

但是,在上述问题的上下文中,用户向我们通知了一个错误.我修改了一点Redis 3.0的实现,以便在wait3()返回-1 时清楚地记录,而不是因为这种意外情况而崩溃.所以这就是显而易见的事情:

  1. wait3() 当有待等待的孩子时,我们会打电话.
  2. SIGCHLD应设置为SIG_DFL,没有代码Redis的所有设置这个信号,所以它的默认行为.
  3. 当第一次AOF重写发生时,wait3()按预期成功运行.
  4. 从第二次AOF重写开始(创建第二个子项),wait3()开始返回-1.

AFAIK在我们调用的当前代码中wait3()是不可能的,因为当没有挂起的子节点时,因为当创建AOF子节点时,我们设置server.aof_child_pid为pid的值,并且我们仅在成功wait3()调用之后重置它.

所以wait3()应该没有理由失败-1 ECHILD,但它确实如此,所以可能僵尸孩子不是出于某种意想不到的原因而创建的.

假设1:在某些奇怪的条件下Linux可能会丢弃僵尸孩子,例如因为内存压力?看起来不合理,因为僵尸只附加了元数据但谁知道.

请注意,我们打电话wait3()WNOHANG.并且鉴于默认情况下SIGCHLD设置为SIG_DFL,唯一应该导致失败并返回-1的条件,并且ECHLD应该没有可用于报告信息的僵尸.

假设2:可能发生的其他事情但是没有解释,如果它发生,是在第一个孩子死后,SIGCHLD处理程序被设置为SIG_IGN,导致wait3()返回-1和ECHLD.

假设3:有没有办法从外部移除僵尸儿童?也许这个用户有某种脚本可以在后台删除僵尸进程,以便信息不再可用wait3()?据我所知,如果父母不等待它(使用或处理信号)并且如果没有被忽略,则永远不可能移除僵尸,但也许有一些特定于Linux的方式.waitpidSIGCHLD

假设4:实际上有在Redis的代码一些bug,使我们成功wait3()的孩子第一次不正确复位状态,后来我们叫wait3()连连,但不再有僵尸,所以它返回-1.分析代码看起来不可能,但也许我错了.

另一件重要的事情:我们过去从未见过这一点.这显然只发生在这个特定的Linux系统中.

更新:Yossi Gottlieb提出 …

c linux system-calls zombie-process waitpid

31
推荐指数
1
解决办法
1624
查看次数

Xcode在运行iOS测试/模拟器后离开僵尸进程

在iOS应用程序上使用Xcode几天后,我注意到有超过100个僵尸进程闲逛.似乎每次运行单元测试都有一个,每次我在模拟器中运行完整的应用程序时可能有一个.这是一个示例(清理和截断):

> ps -efj | grep $PRODUCT_NAME
  502  2794   236   0 Wed12AM ??         0:00.00 (MyProduct)  me            2794      0    1 Z      ?? 
  502  2843   236   0 Wed01AM ??         0:00.00 (MyProduct)  me            2843      0    1 Z      ?? 
  502  2886   236   0 Wed01AM ??         0:00.00 (MyProduct)  me            2886      0    1 Z      ?? 
...
  502 13711   236   0 Thu11PM ??         0:00.00 (MyProduct)  me           13711      0    1 Z      ?? 
  502 13770   236   0 Thu11PM ??         0:00.00 (MyProduct)  me           13770      0    1 Z      ?? 
  502 14219 …
Run Code Online (Sandbox Code Playgroud)

xcode zombie-process

24
推荐指数
2
解决办法
4677
查看次数

在运行命令变成僵尸后,Docker容器拒绝被杀死

首先要做的事情.我的系统信息和版本:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 13.04
Release:    13.04
Codename:   raring

$ sudo docker version
Client version: 0.9.0
Go version (client): go1.2.1
Git commit (client): 2b3fdf2
Server version: 0.9.0
Git commit (server): 2b3fdf2
Go version (server): go1.2.1

$ lxc-version
lxc version: 0.9.0

$ uname -a
Linux ip-10-0-2-86 3.8.0-19-generic #29-Ubuntu SMP Wed Apr 17 18:16:28 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

在它内部的过程变成僵尸之后,我无法阻止容器.升级到docker 0.9.0后,我的服务器上看到了大量的僵尸.例:

$ ps axo stat,ppid,pid,comm | grep -w defunct
Zl   25327 …
Run Code Online (Sandbox Code Playgroud)

linux zombie-process lxc docker

21
推荐指数
1
解决办法
8715
查看次数

Python-daemon不会杀死它的孩子

使用python-daemon时,我正在创建子进程likeo:

import multiprocessing

class Worker(multiprocessing.Process):
   def __init__(self, queue):
      self.queue = queue # we wait for things from this in Worker.run()

   ...

q = multiprocessing.Queue()

with daemon.DaemonContext():
    for i in xrange(3):
       Worker(q)

    while True: # let the Workers do their thing
       q.put(_something_we_wait_for())
Run Code Online (Sandbox Code Playgroud)

当我用Ctrl-C或SIGTERM等杀死父守护进程(即不是Worker)时,孩子们不会死.怎么杀了孩子?

我的第一个想法是使用atexit杀死所有的工人,喜欢:

 with daemon.DaemonContext():
    workers = list()
    for i in xrange(3):
       workers.append(Worker(q))

    @atexit.register
    def kill_the_children():
        for w in workers:
            w.terminate()

    while True: # let the Workers do their thing
       q.put(_something_we_wait_for())
Run Code Online (Sandbox Code Playgroud)

但是,守护进程的孩子们处理起来很棘手,我不得不考虑如何做到这一点并提出意见.

谢谢.

python children daemon multiprocessing zombie-process

20
推荐指数
1
解决办法
8065
查看次数