1
lhy360121 2015-05-19 09:53:32 +08:00
像爬虫这种io密集的任务用多线程就好,开进程比开线程消耗的系统资源多。 cpu密集的任务才用多进程。
你运行的时候,可以看看2中情况下系统消耗的资源,做个对比。 另外,你用的什么系统。。 |
2
nicksite 2015-05-19 09:57:53 +08:00
像这种IO密集的,主要瓶颈不是在于网络的通畅么。
|
4
bengol 2015-05-19 10:10:24 +08:00
你能先把profiler挂上么
|
5
clino 2015-05-19 10:15:34 +08:00
"多进程开辟了50个子进程,执行完毕100s和用for循环差不多,而且奇卡无比"
估计你使用姿势不当 另外爬虫是不是也可以考虑用协程如gevent,占用资源更少 |
6
zzh161 2015-05-19 10:38:37 +08:00
网络或者磁盘操作,这种IO密集型的任务多线程在提高效率方面会比较明显吧。如果是计算密集型的,那python的多线程就无法提高效率,甚至会降低效率,这方面可以自行搜索“python GIL锁”
另外,楼上说的用协程,在楼主所说的这种情况下,应该效率不会比多线程高,因为协程是单线程的,同时只能有一个任务在执行,考虑到爬虫还要读页面,解析页面,这里面有不少是计算任务,如果不是网络很慢的情况下,还是会造成很多网页读好了,等待解析。 |
7
jimzhong 2015-05-19 11:15:28 +08:00
请问楼主在什么平台下跑程序的。如果windows进程开销会比线程大一些,希望我没有搞错。多进程也会共享内存的,一般都是在写入时复制。
由于CPython的多进程实际上不是在多个核心上跑的。所以多线程性能并不会提升吧。 |
8
quix 2015-05-19 14:21:03 +08:00
爬虫用异步 io 就行吧.. 无须并行
|
9
chevalier 2015-05-19 14:27:53 +08:00
爬虫90%的时间都是网络等待,用异步吧
|
10
caoyue 2015-05-19 14:46:36 +08:00
上面大家说的都有道理,具体到楼主的问题,多进程消耗是会比多线程大一点,但是应该不至于大到 10 倍吧
方便的话可以贴个代码,方便大家分析 |
11
est 2015-05-19 14:52:53 +08:00
贴newrelic。
|
12
cc7756789 OP import requests
from bs4 import BeautifulSoup import multiprocessing n = 0 url_list = ['http://ubuntuforums.org/forumdisplay.php?f=333', ] for x in range(1, 50): n += 1 raw_url = 'http://ubuntuforums.org/forumdisplay.php?f=333&page=%d' % n url_list.append(raw_url) def running(url, q, lock): lock.acquire() html = requests.get(url) if html.status_code == 200: html_text = html.text soup = BeautifulSoup(html_text) with open('/home/zhg/Pictures/cao.txt', 'a+') as f: for link in soup.find_all('a', 'title'): s = 'http://ubuntuforums.org/' + str(link.get('href')) + ' ' + str(link.get_text().encode('utf-8')) f.writelines(s) f.writelines('\n') lock.release() if __name__ == '__main__': manager = multiprocessing.Manager() p = multiprocessing.Pool(len(url_list)) q = manager.Queue() lock = manager.Lock() for x in url_list: p.apply_async(running, args=(x, q, lock)) p.close() p.join() print "process ended" |
13
Valyrian 2015-05-19 14:58:23 +08:00
多进程比多线程费资源这是基础知识吧
|
14
JackeyGao 2015-05-19 14:59:16 +08:00
计算密集采取多进程充分利用CPU多核心优势, I/O密集等待时间过多采取多线程。
如果是python 2.7 或者 python 3.2+的话, 推荐使用concurrent.futures 做异步并发 |
15
WKPlus 2015-05-19 17:22:58 +08:00 1
你的running函数一把锁从头加到尾,怎么并行执行啊?
|
16
hitsmaxft 2015-05-19 17:31:47 +08:00
这点小任务那还用得着讲究到这个地步, 一般多核多线程效率够了, io 密集型大不了上协程或者 reactor 之类的。
多进程为的是资源隔离,或者弥补那些多核支持不好的语言 |
17
kingname 2015-05-19 18:37:12 +08:00
多线程使用map会比使用threading好用。
请戳http://jikexueyuan.com/course/902.html |
18
matrix67 2015-05-19 18:56:38 +08:00 via Android
dummy呀
|
20
WKPlus 2015-05-19 19:09:31 +08:00
@cc7756789 锁用来防止不能并发执行的代码被并发执行
你的running函数里面不能并发执行的地方应该是写文件那块,你可以把结果返回最后统一写文件 |
21
9hills 2015-05-19 19:13:45 +08:00 via iPhone
Lz 这个锁加的。
|
23
wind3110991 2015-05-19 23:46:25 +08:00 1
@cc7756789 可以用下markdown语法。。强迫症看python难受 = 。 =
```python import requests from bs4 import BeautifulSoup import multiprocessing n = 0 url_list = ['http://ubuntuforums.org/forumdisplay.php?f=333', ] for x in range(1, 50): n += 1 raw_url = 'http://ubuntuforums.org/forumdisplay.php?f=333&page=%d' % n url_list.append(raw_url) def running(url, q, lock): lock.acquire() html = requests.get(url) if html.status_code == 200: html_text = html.text soup = BeautifulSoup(html_text) with open('/home/zhg/Pictures/cao.txt', 'a+') as f: for link in soup.find_all('a', 'title'): s = 'http://ubuntuforums.org/' + str(link.get('href')) + ' ' + str(link.get_text().encode('utf-8')) f.writelines(s) f.writelines('\n') lock.release() if __name__ == '__main__': manager = multiprocessing.Manager() p = multiprocessing.Pool(len(url_list)) q = manager.Queue() lock = manager.Lock() for x in url_list: p.apply_async(running, args=(x, q, lock)) p.close() p.join() print "process ended" ``` |
24
slideclick 2015-05-20 10:33:00 +08:00
windows系统创建进程开销很大。另外IO密集型,多线程就够了。
什么时候用多进程?CPU密集的,这时需要利用多核,python只有进程才可以分布的多个核上面,线程做不到分布。 |