之前也写了一些简单的Python程序,对于多线程的并发一直没有涉及,今天决定先突破一下,把这个部分的内容先快速的掌握,然后在这个基础上细化改进。
我的好友冰川擅长Python技术,所以就拿来主义,参考了他的文章。
python基础16-并发编程(1)
Python的程序性能一直受到诟病,但是功能,扩展性上还是具有很大的优势,程序中有一部分的概念就是并发,多线程相关的,所以我们也算是大跃进一下。
说到Python的性能,GIL是需要了解的,这是一个全局解释器锁,保证在同一时刻只有一个线程在运行,在保证线程安全的同时,性能上会受到一定的影响。我们简单来做一个案例,在上面的文章中已经有了,我们简单改一下。测试一把。
首先要准备一个文件urls.txt
比如我的技术博客,我随便选择了两篇文章的下标,然后就可以循环生成一大批的urls.txt内容来。
for i in {2101076..2148323}
do
echo "http://blog.itpub.net/23718752/viewspace-"$i
done
要测试url的信息,我们需要引入一个模块requests,通过发送请求来得到反馈的结果,如果是在200,300这样的状态值,就说明是可访问的,否则就是不可方案问。
需要注意的地方或者是一些小技巧,我们可以使用strip()来得到一个串
>>> "http://www.jeanron100.com".strip()
'http://www.jeanron100.com'
,然后使用requests.get方法来得到结果值
>>> requests.get('http://www.baidu.com')
最终的状态值可以使用status_code属性来得到。
>>> requests.get('http://www.baidu.com').status_code
200
明白了这些要点,Python程序就会容易很多。
直接附上源程序:
#!/usr/bin/evn python
import requests
import time
def get_site_code(url):
r = requests.get(url)
status = r.status_code
line = url + ' ' + str(status)
with open('/tmp/site_stauts.txt', 'a+') as f:
f.writelines(line + 'n')
if __name__ == '__main__':
print 'starting at:', time.ctime()
for url in open('urls.txt'):
url = url.strip()
get_site_code(url)
print 'Done at:', time.ctime()
整个过程,大概耗时37秒钟,urls大概是30多个。
# python a.pl
starting at: Wed Dec 6 07:00:34 2017
Done at: Wed Dec 6 07:01:11 2017
我们再来看看多线程的部分,毫无疑问,我们需要一个线程相关的模块,在这里就是threading
我们可以直接开启多个线程,不做线程的粒度控制,比如现在有30个请求,直接就是30个线程,暂时没有做成线程池的那种模式,初始化的时候,可以使用如下的方式来初始化线程。
threading.Thread(target=get_site_code, args=(url,))
使用start方法启动线程
threads[i].start()
如果一个线程在执行过程中要调用另外一个线程,需要等到它完成以后才能接着执行,在这里就是join方法。
threads[i].join()
源程序如下:
#!/usr/bin/evn python
import requests
import time
import threading
def get_site_code(url):
r = requests.get(url)
status = r.status_code
line = url + ' ' + str(status)
with open('/tmp/site_stauts.txt', 'a+') as f:
f.writelines(line + 'n')
if __name__ == '__main__':
print 'starting at:', time.ctime()
threads = []
for url in open('urls.txt'):
url = url.strip()
t = threading.Thread(target=get_site_code, args=(url,))
threads.append(t)
for i in range(len(threads)):
threads[i].start()
for i in range(len(threads)):
threads[i].join()
print 'Done at:', time.ctime()
使用了多线程之后,耗时大概是3秒钟,提高了10多倍,收益还是很大的。
# python b.pl
starting at: Wed Dec 6 07:24:36 2017
Done at: Wed Dec 6 07:24:39 2017
随后会考虑从其他的角度来持续的改进,改进的空间依旧很大。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23718752/viewspace-2148810/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/23718752/viewspace-2148810/