我需要帮助修复管道中杂乱代码的关键部分。
我在scratchy中使用这个MySQL管道(来自http://snippets.scrapy.org/snippets/33/):
class SQLStorePipeline(object):
def __init__(self):
self.dbpool = adbapi.ConnectionPool('MySQLdb', db='mydb',
user='myuser', passwd='mypass', cursorclass=MySQLdb.cursors.DictCursor,
charset='utf8', use_unicode=True)
def process_item(self, item, spider):
# run db query in thread pool
query = self.dbpool.runInteraction(self._conditional_insert, item)
query.addErrback(self.handle_error)
return item
def _conditional_insert(self, tx, item):
# create record if doesn't exist.
# all this block run on it's own thread
# START CRITICAL SECTION
some_critical_code_here
# STOP CRITICAL SECTION
tx.execute("select * from websites where link = %s", (item['link'][0], ))
result = tx.fetchone()
if result:
log.msg("Item already stored in db: %s" % item, level=log.DEBUG)
else:
tx.execute(
"insert into websites (link, created) "
"values (%s, %s)",
(item['link'][0],
datetime.datetime.now())
)
log.msg("Item stored in db: %s" % item, level=log.DEBUG)
def handle_error(self, e):
log.err(e)
一切都很好。
正如您所看到的,我已经知道代码中的关键部分在哪里了。但是我真的是python的新手并且不知道如何使用一些锁或类似的东西来防止多个线程进入crical部分。
你能帮帮我吗?如果你能把我可以在这个代码中使用的进入和离开关键部分的代码发给我,那就太好了。
伙计们。
即使您使用的是Twisted,通常涉及阻塞的所有操作都需要以不同的方式进行,但您所处的Twisted的特定部分可以进行阻塞。因此,这应该很简单,只需分配一个所有线程都可以引用的Lock对象,然后获取它:
import threading
insert_critical_lock = threading.Lock()
...
def _conditional_insert(self, tx, item):
with insert_critical_lock:
# START CRITICAL SECTION
some_critical_code_here
# STOP CRITICAL SECTION
tx.execute("select * from websites where link = %s", (item['link'][0], ))
...
无论如何,我通过合并关键部分中的sql语句来进行排序thx到家伙与nick toothrot上的想法