我有一个旧样式表,现在充满了未使用的样式.问题是从不必要的角度确定必要的.有没有工具可以帮助解决这个问题?
我正在使用multiprocessing.Pool和实现python中的生产者 - 消费者模式multiprocessing.Queue.消费者是gevent用于产生多个任务的预分叉进程.
这是一个精简版的代码:
import gevent
from Queue import Empty as QueueEmpty
from multiprocessing import Process, Queue, Pool
import signal
import time
# Task queue
queue = Queue()
def init_worker ():
# Ignore signals in worker
signal.signal( signal.SIGTERM, signal.SIG_IGN )
signal.signal( signal.SIGINT, signal.SIG_IGN )
signal.signal( signal.SIGQUIT, signal.SIG_IGN )
# One of the worker task
def worker_task1( ):
while True:
try:
m = queue.get( timeout = 2 )
# Break out if producer says quit …Run Code Online (Sandbox Code Playgroud) 我有一些进程显示<defunct>在top(和ps)中.我从真实的脚本和程序中榨取了一些东西.
在我的crontab:
* * * * * /tmp/launcher.sh /tmp/tester.sh
Run Code Online (Sandbox Code Playgroud)
的内容launcher.sh(这是当然的标记为可执行):
#!/bin/bash
# the real script does a little argument processing here
"$@"
Run Code Online (Sandbox Code Playgroud)
的内容tester.sh(这是当然的标记为可执行):
#!/bin/bash
sleep 27 & # the real script launches a compiled C program in the background
Run Code Online (Sandbox Code Playgroud)
ps 显示以下内容:
user 24257 24256 0 18:32 ? 00:00:00 [launcher.sh] <defunct>
user 24259 1 0 18:32 ? 00:00:00 sleep 27
Run Code Online (Sandbox Code Playgroud)
请注意,tester.sh它不会出现 - 它在启动后台作业后退出.
为什么要launcher.sh坚持,标记<defunct> …
我想使用fork> exec过程创建许多子进程.许多过程都以非常快的速度结束(不到两分钟,有些甚至更早).
我的第一个问题是,我将生成的进程放入后台
./spawnbot > logging.txt
[CTRL+Z]
bg 1
disown
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.现在我不再看到任何spawnbot的消息,他们直接进入logging.txt.然而,每当创建一个新的孩子时,我再次在我的控制台中看到关于那个孩子的所有信息..我现在想要用它自己的管道启动每个孩子 - 是否有更好的方法让孩子们在他们的输出消息全部发布安慰?我应该将它重定向到/ dev/null还是用C中的一些标志完成?
其次,所有的孩子都没有真正被杀.我的ps -ef中有很多进程.我该怎么办?我该怎么做
在我的带有内核2.6.18的Fedora Core 9网络服务器上,init并没有收获僵尸进程.如果进程表最终没有达到可以分配新进程的上限,那么这将是可以忍受的.
样本输出ps -el | grep 'Z':
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
5 Z 0 2648 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
1 Z 51 2656 1 0 75 0 - 0 exit ? 00:00:00 sendmail <defunct>
1 Z 0 2670 1 0 75 0 - 0 exit ? 00:00:02 crond <defunct>
4 Z 0 2874 1 0 82 0 - 0 exit …Run Code Online (Sandbox Code Playgroud) 我们先来看看这个现象
Nodejs代码:
const cp = require('child_process');
var ls = cp.spawn('ls', ['/']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process closed with code ${code}`);
});
while(true){}
Run Code Online (Sandbox Code Playgroud)
运行这个nodejs代码,没有显示任何内容,似乎没有触发任何事件。
然后在另一个shell中运行“ps -ef | grep ls | grpe -v grep”,结果是:
liyuanq+ 10995 10990 0 11:06 pts/3 00:00:00 [ls] <defunct>
Run Code Online (Sandbox Code Playgroud)
如果删除代码:
while(true){}
Run Code Online (Sandbox Code Playgroud)
节点进程退出,并触发on data事件。
问题是为什么节点在实际完成其工作时不关闭生成的进程,直到父节点进程退出。
我的环境:
操作系统:Debian 8.4 x86_64
节点:v6.1.0
到底kill是做什么的?
我有一个父进程,它一个接一个地创建100(作为示例)子进程.在任何孩子的工作结束时,我杀了孩子,kill(pid_of_child, SIGKILL)我在ps输出中看不到.但是如果父进程出现问题并且我从父进程退出exit(1)(此时只有1个子进程- 我可以检查它ps),那时我看到很多<defunct>进程ppid是pid父进程的.
怎么可能?没有kill彻底杀死孩子的过程?
我找到了答案,SIGCHLD并wait为该处理程序设置了一个信号处理程序.这样,每当父进程执行kill子进程时,就会调用此处理程序并调用它wait来获取子进程. - 动机是清除进程表条目.
即使没有父进程死亡,我仍然会看到一些子进程持续几秒钟.- 这怎么可能?
我看到了这个ps.准确地ps -o user,pid,ppid,command -ax和父母的过程,子过程和失效.
我们使用python进程来管理长时间运行的python子进程.偶尔需要杀死子程序.kill命令不会完全终止进程,只会使其失效.
运行以下脚本演示了此行为.
import subprocess
p = subprocess.Popen(['sleep', '400'], stdout=subprocess.PIPE, shell=False)
Run Code Online (Sandbox Code Playgroud)
要么
p = subprocess.Popen('sleep 400', stdout=subprocess.PIPE, shell=True)
Run Code Online (Sandbox Code Playgroud)
将创建一个子进程.
p.terminate()
p.kill()
Run Code Online (Sandbox Code Playgroud)
对这个过程没有任何作用.由...证明ps aux | grep sleep
$ ps aux| grep 'sleep'
User 8062 0.0 0.0 7292 764 pts/7 S 14:53 0:00 sleep 400
Run Code Online (Sandbox Code Playgroud)
这个过程没有被杀死/被解散.使用subprocess.call()带有'kill'和pid作为参数的函数将发出kill命令.
subprocess.call(['kill', str(p.pid)])
Run Code Online (Sandbox Code Playgroud)
这会杀死这个过程,但它现在已经不存在了.
$ ps aux | grep 'sleep'
User 8062 0.0 0.0 0 0 pts/7 Z+ 14:51 0:00 [sleep] <defunct>
Run Code Online (Sandbox Code Playgroud)
如果队列运行的时间足够长,它最终会达到最大进程数,还是最终会收到已解散的进程并且没问题呢?
如果答案是前者,我如何在不杀死父进程的情况下处理python中的defunct进程?
有没有更好的杀死进程的方法?