V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  hanssx  ›  全部回复第 56 页 / 共 59 页
回复总数  1170
1 ... 48  49  50  51  52  53  54  55  56  57 ... 59  
我之前写的用 join 的方法不对,join 方法虽然也有 wait 的功能,但是如果单个进程 join 还好,多个进程的话可能在 join 之前进程就已经结束变为僵尸进程,现在的方法是处理 SIGCHILD 信号,这样保证不会有僵尸进程了,至于还会不会有其他问题,下下周再跑程序时反馈,感谢各位的帮助。如果有更好的办法,请告知,红包以表谢意。
这回复不支持 markdown 也有点难受。
@ytymf 确实是的,这个父进程是 celery worker 的,如果不用 celery,这套东西是没问题的,我修改了如下代码:
```
def run(self):
self.scan_list = sorted(self.scan_list) # ['http://2.2.2.2:22', 'http://www.baidu.com', ......]
for url in self.scan_list:
self.queue.put(url)
time.sleep(3) # KLD 将一个对象放入一个空队列后,可能需要极小的延迟,队列的方法 empty()才会返回 False。 参考: https://docs.python.org/zh-cn/3/library/multiprocessing.html
self.scan_start()
```
改为
```
def run(self):
self.scan_list = sorted(self.scan_list) # ['http://2.2.2.2:22', 'http://www.baidu.com', ......]
scan_list_len = len(self.scan_list)
# self.total_domain_cnt = len(self.scan_list)
for url in self.scan_list:
self.queue.put(url)
while self.queue.qsize() != scan_list_len:
time.sleep(3) # KLD 将一个对象放入一个空队列后,可能需要极小的延迟,队列的方法 empty()才会返回 False。 参考: https://docs.python.org/zh-cn/3/library/multiprocessing.html
self.scan_start()
```

```
def scan_start(self):
"""
进程池扫描启动
:return:
"""
for i in range(self.process_count):
t = WebFingerprintDiscernProcess(self.config, self.queue, self.lock)
t.daemon = True
t.start()
self.queue.join()
```
改为
```
def scan_start(self):
"""
进程池扫描启动
:return:
"""
process_list = []
for i in range(self.process_count):
# As far as possible one should try to avoid shifting large amounts of data between processes.
# https://docs.python.org/3/library/multiprocessing.html#multiprocessing-programming
t = WebFingerprintDiscernProcess(self.config, self.queue, self.lock)
t.daemon = True
t.start()
process_list.append(t)
for p in process_list:
p.join()
self.queue.join()
```
不过我的用法确实太奇怪,celery 官方是不推荐在里面使用多进程的,billiard 看 issue 里面好像也要换的意思。
@lolizeppelin 额,spawn 模式启动不起来 celery worker,师父你知道哪儿的问题吗,能说一下吗。
你说的基础知识,我理解可能是信号处理,你是说子进程结束的时候发送 SIGCHILD KILL 之类的信号,如果父进程不处理就会使子进程变为僵尸进程是吧,这个我是知道的,我也避免了,加上了子进程.join()
@lolizeppelin 那个是这样的,本身使用 multiprocessing 没啥问题,在 celery worker 里面使用就会有问题,celery 也给了一个 billiard,算是 multiprocessing 的 patch。
@ytymf 试了一下,celery worker 直接启动不起来,考虑用 canvas 重构一下,还是感谢师父,学到了。
import billiard as multiprocessing
multiprocessing.set_start_method('spawn')
@ytymf 多谢师父,晚上我改一下试试。
@ytymf 多谢指教,学到了。我这个主进程是 celery worker 产生的进程,我代码中并没有用线程,更没有用多线程。僵尸进程产生的原因应该子进程结束之后,父进程仍然存在且没有 wait 或 communicate 子进程,也就是没处理子进程发来的 SIGCHILD KILL 那个信号。
@hhbcarl 谢谢师父,你说的这个 canvas 之前有了解,但是现在项目代码不太容易改,周末尝试一下。
----------------------------------------------------------------------------------------------------------------------------------------
@ClericPy 是僵尸进程,Z 代表 Zombie,僵尸进程产生的原因是因为子进程结束之后,父进程仍然存在且没有 wait 或 communicate 子进程,产生原因我倒是清楚,只是不明白为什么一开始就有子进程结束,因为队列里面的东西很多,不可能一开始子进程就结束的。
----------------------------------------------------------------------------------------------------------------------------------------
@ytymf “multiprocessing 一定要确保父进程是单线程的”,这个是啥意思呀,是确保父进程是单进程吧? celery worker 里面看确实是单进程。
2019-10-25 11:58:04 +08:00
回复了 zbl430 创建的主题 Linux QQ For Linux 我哭了,官方版
要是有企业微信就好了。
2019-10-21 17:30:02 +08:00
回复了 eteryao 创建的主题 Python celery +redis missed heartbeat from celery
换用 rmq 吧,redis 不建议使用在生产环境中。
前几天我使用 celery v4.3 + rmq 3.7.7 也遇到了你这问题,好像是网络原因,你不会和我一样执行得是扫描任务吧?
话说这个问题不应该是 INFO 吗?不是 ERROR 吧。
可以尝试把 heartbeat 关掉。
https://stackoverflow.com/questions/21132240/celery-missed-heartbeat-on-node-lost
2019-09-09 11:33:48 +08:00
回复了 hanssx 创建的主题 Python celery worker 多线程执行完后卡住假死
@neoblackcap 嗯,我使用得是你说的 nmap 的 Python 封装库,源码里面使用得也是 subprocess.Popen(),额,需要时可加我扣扣,随时欢迎师父加我。
2019-09-08 10:27:04 +08:00
回复了 hanssx 创建的主题 Python celery worker 多线程执行完后卡住假死
已确定为 logging 死锁问题,50 块钱由崔庆才师父和 @neoblackcap 师父平分,
@neoblackcap 师父,加我一下扣扣 9 六 14 六 2392,把支付宝账号发我即可。
2019-09-04 22:49:49 +08:00
回复了 hanssx 创建的主题 Python celery worker 多线程执行完后卡住假死
多进程可以解决这个问题,之前 @崔庆才师父说可能是 logging 死锁的问题,很有可能,待下一步确定。
2019-09-03 16:15:57 +08:00
回复了 hanssx 创建的主题 Python celery worker 多线程执行完后卡住假死
2019-09-03 Update:
已经修改为 multiprocessing 多线程,但实际测试时,celery 不能直接使用 multiprocessing,解决方案参见 https://stackoverflow.com/questions/30624290/celery-daemonic-processes-are-not-allowed-to-have-children
因为使用 cavas 改动比较大,所以我直接使用得 import billiard as multiprocessing
目前运行中,持续观察。
2019-09-03 11:08:28 +08:00
回复了 hanssx 创建的主题 Python celery worker 多线程执行完后卡住假死
@xixijun 感谢 xixijun 师父的回答,请问师父你说的可以,是指使用多进程来代替多线程吗?我这边扫的是公司全网,就是扫完之后 celery worker 就卡住假死了,具体详情可查看一下问题描述。
2019-09-02 23:40:41 +08:00
回复了 lbfeng 创建的主题 Python Thread join 有点困惑
正如 4l 所说,t1.join()有意义,t5 所需时间比 t1 长,所以这个代码可以只用 t5.join(),但是实际当中复杂场景你怎么知道哪个线程时间长呢?
另附 join vs. wait 中文区别
线程运行 sleep()或 join()方法后,线程进入 Sleeping 状态。区别在于 sleep 等待固定的时间,而 join 是等待子线程执行完。当然 join 也可以指定一个“超时时间”。从语义上来说,如果两个线程 a、b, 在 a 中调用 b.join(),相当于合并(join)成一个线程。最常见的情况是在主线程中 join 所有的子线程。
2019-09-02 18:46:11 +08:00
回复了 hanssx 创建的主题 Python celery worker 多线程执行完后卡住假死
@neoblackcap 我不明白为啥不可以,我先试试用多进程,你也说了 celery 对线程支持有缺陷,网络请求的阻塞是必然的。
2019-09-02 16:47:12 +08:00
回复了 hanssx 创建的主题 Python celery worker 多线程执行完后卡住假死
@neoblackcap 谢谢,gevent 实现 nmap 的功能基本不可能,必须得使用 subprocess.Popen 去调用 nmap,这种情况下,我使用多进程代替多线程可以吗?你之前说进程或者 gevent 都可以。
2019-09-02 14:45:58 +08:00
回复了 akmonde 创建的主题 Python celery 处理结果的入库问题
考虑做成 RPC ?
1 ... 48  49  50  51  52  53  54  55  56  57 ... 59  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2599 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 24ms · UTC 10:43 · PVG 18:43 · LAX 02:43 · JFK 05:43
Developed with CodeLauncher
♥ Do have faith in what you're doing.