Python线程通信

Python线程通信

Author:palydawn

Date:2012.5.23

Email:palydawn@163.com

 

    最近用python写了一个网络爬虫,很多个线程同时抓取网页。程序里面设定的线程停止条件是下载的网页数大于一个实现确定的阈值,由于阈值常常设得比较大,有时候在程序跑了一段时间之后发现一些问题,只能暴力终止下来调试程序,这个时候会遇到一个问题,我的程序里面用BerkeleyDB来保存url的,python2.7自带的BerkeleyDB貌似很久才会将内存中的数据同步到文件中,贸然终止程序非常可能会造成数据的丢失,所以我选择了下载一定数量的网页之后手动同步一次,这又有了新的问题,暴力终止程序时可能会打断内存数据同步到文件中的过程,造成数据库文件损坏,读取数据库文件时引发异常。这种时候几个小时得到的数据就丢失了(当然也可以通过文件日志的方式记录已经下载的和将要下载的url等信息,但是我不愿意这么做,而且老是这么暴力也不是办法)。

    今天试了一下python的线程通信,发现使用Event可以解决这个问题。

    Python里面Event的用法很简单。使用threading.Event()可以得到event对象,Event中内置了一个标志,初始值为False。调用Event的set()方法可以将内置标志设为True,调用Event的clear()方法可以将内置标志设为False,使用isSet()可以检查内置标志的当前状态,调用Event的wait()方法会将线程阻塞,直到当前Event的状态被其他线程设置为True。

下面是一个简单的例子。(网上到处都是这种例子,不过针对我的目的,有些改动)。

'''

Created on 2012-5-23

 

@author: palydawn

'''

import threading

import time

 

class MyThread(threading.Thread):

    def __init__(self, threadName, event):

        threading.Thread.__init__(self, name = threadName)

        self.threadEvent = event

 

    def run(self):

        print '%s is ready' % self.name

        while True:

            if self.threadEvent.isSet():

                print '%s run' % self.name

                time.sleep(0.1)

            else:

                print '%s stop' % self.name

                break

#start work

event = threading.Event()

event.set()

for i in range(5):

t = MyThread(str(i), event)

t.start()

time.sleep(5)

order = raw_input('input order:')

if order == 'q':

event.clear()

 

将同一个Event对象传给5个线程,线程启动之后执行里面的run()方法,首先检查Event的内置值是否为True,是则进行操作

"print '%s run' % self.name"

否则终止循环,退出线程。在启动线程之前已经将Event的内置值设置为True了(event.set()),所以每个线程启动之后都在不停地运行。在主线程中

order = raw_input('input order:')

用于接收控制台的命令信息,当在控制台输入'q'时,通过event.clear()event的内置标志设为False,线程检查到event内置标志状态为False,就会停止。没有使用wait()方法,因为我的程序里面用不上。程序运行结果如下。


0 is ready

0 run

is ready

1 run

is ready

2 run

is ready

3 run

is ready

4 run

q0 run

4 run

3 run

1 run

2 run

 

0 run3 run1 run2 run

 

 

 

4 run

0 run3 run1 run2 run

 

 

 

4 run

3 run

1 run

2 run

0 run

4 run

input order:0 stop

4 stop

3 stop1 stop2 stop


    由于多线程打印输出时间的不确定性,上面的打印出来的信息时间上有错乱,不过不影响结果的正确定,在控制台输入'q'之后(仔细看可以看到我确实输入了q,),所有的线程停止了运行。这个例子模拟了网络爬虫运行和停止的情况,在爬虫中只需要在检查到event内置标志为False是做好数据的同步和一些其他数据的保存工作再终止线程即可。对上面的例子稍作修改,在控制台循环等待order还可以做更多的事情,以达到对线程的精确控制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值