python杀死线程

[源] = [ http://hi.baidu.com/leoomo/blog/item/c9bbf25c99ffe14bfaf2c006.html]

python杀死线程
2009年05月13日 星期三 22:32
我曾经碰到过类似问题,研究后的结论是,问题出在python没有杀死线程的API上。
python对于线程只能去join,或者给线程发送信号来终止。但是我使用pycurl库的时候,挂死在网络上,他就没办法了。
我的解决方案平台相关了,是使用getId来获得ID,然后通过WindowsSDKAPI调用来强行Trim。
用子进程是一种不错的方案,因为python是可以kill掉某个进程的。不过相对来说,进程间数据共享比线程要复杂多了。
现在还有一种方案,但是我没有研究的,是使用twisted的多线程模型。
其他就想不出了,希望大家提供更好的方案。

Dong Lee 写道:
 
几个建议:

1、你那个服务进程应该自己daemonize;
2、服务进程应该保存pid到文件;
3、watchdog根据pid文件中的pid检查服务进程是否还在运行中;(运行状态是否正常可以还是用你说的时间比对);
4、一般来说,杀不死那个服务进程是权限问题,所以,可以考虑直接由watchdog作为自己的子进程来启动服务进程。

DIrk
您的建议非常好, 是一种非常好的思路.  不过我还不会用 watchdog 启动子进程, 是用fork 吗, 另外父进程如果直接能杀掉子进
程, 那问题就简单了,

您能提供一个非常简单的小例子吗. 非常感谢.

其实我还考虑过用多线程来做, 多线程程序也同样存在相同的问题, 就是主线程启动了多个子线程之后, 是可以监控到某个子线程长时间停止响应,
可以知道那个线程出现问题, 往往是网络通讯的问题, 但是问题是, 主线程并没有办法去杀掉 或者说终止子线程, 只能发信号,告诉子线程终止自
己,
但子线程已经停止响应, 可能堵在网络通讯那里了, 所以子线程杀不掉, 只能另外开一个线程. 这样线程就会越来越多.

现在回到进程处理这里, python 可以用父进程创建子进程, 并根据子进程pid 杀掉某个子进程吗.

有经验的程序高手, 请指点一二 .
On 4月11日, 下午10时48分, Li Dong lidon...@... wrote:
做了一个爬虫程序, 不过运行一段时间后, 总是莫名奇妙的就不工作了, 所以,我需要另外一个监控程序,定时看看爬虫程序工作是否正常,不正常就kill
掉进程,然后重启一个进程。
我是在linux 下面运行程序的。
想法其实特别简单, 别人在网上也提出过这个想法的,就是监控日志文件, 让爬虫程序定时写日志文件(写当前时间), 然后监控程序定时读取监控文件最后一行,
然后和当前时间比较, 如果时间差异在允许范围内,算爬虫工作正常, 否则,就要杀掉爬虫进程,然后重启爬虫。 想法是如此简单,
应该也是有效的,但是运行过程中,发现监控程序无法杀死爬虫进程, 导致系统中运行了一段时间后,有大量的爬虫程序, 要多少有多少。 附代码如下, 望高手,
或者有这方面经验的高手指点一二, 不胜感激。 主要就是我杀掉进程用的是
1, 找爬虫进程ID:
     ps_str = 'ps aux |grep %s | grep -v grep' %proc_name
    #ps_str = 'ps |grep testlong.py | grep -v grep'
    x= os.popen(ps_str).read()
2, 杀进程
  os.system('kill %s' %proc_id)
3, 新建一个进程
   os.system('./%s &' %proc_name)
  是因为那个 & 符号把进程防后台运行了吗, 去掉那个 &符号也不行。 奇怪。
创建进程肯定没问题,可以创建很多个。可是我目前只要有一个进程能好好工作就行,所以我需要在发现进程不工作的时候去杀掉,但是却没办法作到。
下面是一个模拟需要长时间持续运行的一个任务, 比如一个爬虫程序。
#!/usr/bin/env python
#coding=utf-8
'''
$Id$
Filename "longtest.py"
模拟一个需要持久工作的任务
每隔一定时间写日志, 另外一个监控程序定时检查日志,
如果日志最后时间和当前时间差距超过一定值,就杀掉
本程序,然后重新打开这个程序。
'''
import time
import datetime
def main():
print 'now begin at ',datetime.datetime.now()
    count = 1
    while 1:
        count += 1
        time.sleep(5)
        if count < 10:
            str_time = datetime.datetime.strftime(
                    datetime.datetime.now(), '%Y-%m-%d %H:%M:%S')
            fp = open('runlog.log','aw')
            fp.write('%s\n' %str_time)
            fp.close()
            print 'still work... %s' %count
        # 就是说执行10次之后,模拟本程序死掉了,不写日志了
        else:
            print 'dont work... %s' %count
    print 'done', datetime.datetime.now()
if __name__ == '__main__':
    main()
============ 监控程序如下 =============
#!/usr/bin/env python
#coding=utf-8
import os
import datetime
import time
# 要kill掉的进程的名字描述字符串.
proc_name = 'testlong.py'
monit_log = 'runlog.log'
time_allow = 60 # 允许60秒的空闲,超过这个值watchdog 返回0
def log(str):
    p = open('proc.log','aw')
    p.write('%s %s \n' %(str, datetime.datetime.now()))
    p.close()
def watchdog():
    '''检查一个日志文件,取出最后一条记录,
    取出时间,和当前时间比较,看看是否超时。
    超时是time_allow
    超时返回 1, 不超时返回 0
    '''
    fp = open(monit_log,'r')
    lastline = fp.readlines()[-1].replace('\n','')
    fp.close()
    print lastline
    t1 = datetime.datetime.strptime(lastline, '%Y-%m-%d %H:%M:%S')
    timediff = (datetime.datetime.now() - t1).seconds
    print u'上次运行距今 %s 秒' % timediff
    #时间比较
    if timediff > time_allow:
        return 1
    else:
        return 0
def restart_proc(proc_name):
    '''重启指定的进程'''
    ps_str = 'ps aux |grep %s | grep -v grep' %proc_name
    #ps_str = 'ps |grep testlong.py | grep -v grep'
    x= os.popen(ps_str).read()
    #log x
    if x:
        proc = x.split('\n')
        for line in proc:
            print line
            try:
                proc_id = line.split()[0]
                #log ('got pid: %s and kill it ' %proc_id )
                os.system('kill %s' %proc_id)
                log ('kill pid %s ok, starting new' %proc_id)
            except:
                pass
    else:
        # 没有找到要结束的进程,直接启动该进程
        log ('not find proc, start it ')
    os.system('./%s &' %proc_name)
def main():
    while 1:
        if watchdog():
            restart_proc(proc_name)
        else:
            print 'ok, program well'
        time.sleep(20)
if __name__=='__main__':
   main()

Yours Li Dong

你可能感兴趣的:(Python)