我写了一个多线程的爬虫,在保存我创建的DataFrame后,发现六个线程只有三个线程的文件保存了,其余都没有保存,是不是存在保存冲突?
这是我的 多线程函数
def thread_run():
a=threading.Thread(target=crawler_data,args=('id0',))
b=threading.Thread(target=crawler_data, args=('id1',))
c=threading.Thread(target=crawler_data, args=('id2',))
d=threading.Thread(target=crawler_data, args=('id3',))
e=threading.Thread(target=crawler_data, args=('id4',))
f=threading.Thread(target=crawler_data, args=('id5',))
threading_list=[a,b,c,d,e,f]
for i in threading_list:
i.start()
for i in threading_list:
i.join()
我认为要看保存成功的文件是由哪三个线程完成的。
如果是前3个线程(a,b,c)保存成功,后三个线程(d,e,f)保存失败,那么较大概率是你的这个函数逻辑的问题。由于你的爬虫是在子线程中运行的,那么它不会阻塞主线程的运行,因此很有可能后3个线程刚刚在第1个for循环中被调用start()启动,还没来得及完成保存任务,就在第2个for循环中被调用join()中止了,因此保存失败。
如果不是,那么应当考虑是否存在冲突,可以用线程锁来解决这个问题。或者是声明一个字符串/字节的IO流对象(在io模块中),在子线程中给这个流对象追加字符,最后在主线程或者最后一个子线程中将IO流的内容写入文件。注意最后要调用close()关闭IO流。
我这里给一个第一种情况的大致解决方案,没有上机验证,仅供参考。
def thread_run():
global done
done = {0: False, 1: False, 2: False, 3: False, 4:False, 5:False}
a=threading.Thread(target=crawler_data,args=('id0',))
b=threading.Thread(target=crawler_data, args=('id1',))
c=threading.Thread(target=crawler_data, args=('id2',))
d=threading.Thread(target=crawler_data, args=('id3',))
e=threading.Thread(target=crawler_data, args=('id4',))
f=threading.Thread(target=crawler_data, args=('id5',))
threading_list=[a,b,c,d,e,f]
for i in threading_list:
i.start()
list_ = threading_list.copy()
while True:
index = 0
for i in list_:
if done[index]:
list_.remove(list_.find(i))
i.join()
continue
if done[0] and done[1] and done[2] and done[3] and done[4] and done[5]:
# 所有线程均已结束任务
break
def crawler_data(arg):
# 任务
done[int(arg[2])] = True