python2.7 协程,如何调度运行两个协程?

王胖胖
  • 29

我想在爬虫文件里定义两个协程,一个是save_task,另一个是get_task。但是运行这个py文件后,每次都是save运行完之后才开始运行get,如何调度两个协程,在save的时候也进行get???
对协程还不是很了解,
如果用多线程,还需要加锁,对爬虫会有速度影响。

以下是示例代码

#-*-coding:utf-8-*-
from setting import mongo_host,mongo_port,mongo_db_name_data,mongo_db_name_linkbase,mongo_db_name_task
import pymongo
import gevent
from gevent import monkey
monkey.patch_all()



class Connect_mongo(object):
    def __init__(self):
        self.mongo_host = mongo_host
        self.mongo_port = mongo_port
        self.conn()

    def conn(self):
        self.client = pymongo.MongoClient(host=self.mongo_host,port=self.mongo_port)
        self.db_data = self.client[mongo_db_name_data]
        self.db_linkbase = self.client[mongo_db_name_linkbase]
        self.db_linkbase_collection = self.db_linkbase.linkbase
        self.db_task = self.client[mongo_db_name_task]

    def insert_db(self,item):
        self.db_data.test_task.insert(item)

    def get_task(self,max_requests=10):
        task = []
        for i in range(max_requests):
            result = self.db_data.test_task.find_one_and_delete({})
            task.append(result)
        return task


mongo_insert = Connect_mongo()

def test1():
    for i in xrange(100):
        data = {}
        data['info'] = i
        print '当前插入数值为',i
        mongo_insert.insert_db(data)

def test2():
    for task in mongo_insert.get_task(10):
        print task


save_jobs = [gevent.spawn(test1) for item1 in range(20)]
gevent.joinall(save_jobs)

get_jobs = [gevent.spawn(test2) for item2 in range(20)]
gevent.joinall(get_jobs)

昨天在运行爬虫的时候,save_task有上千个URL,这得等好久才能存储完。

并且还有个问题,我才注意到,存储的数据,20个save_job存储了20个0,有的数据甚至存了34个。一共100个数据,从数据库里查询有3800个。。。。。。

20个save_job协程就是运行了20个程序,存储了20个相同的数值,貌似还可以理解。。。。。。

回复
阅读 2.9k
1 个回答

第一个问题: 如果不用多进程或多线程,你的问题在我知识范围内无解。计算机是从上到下顺序执行的。
第二个问题: 协程就是代码层面的多进程,我是这么理解的。然后你看你的代码,save_task相当于一次性执行了20个相同的函数。所以数据库中一定会有20个相同的数据

宣传栏