一、Python线程和进程
进程
进程是程序的一次执行。每个进程都有自己的地址空间、内存、数据栈及其它记录其运行轨迹的辅助数据。
线程
所有的线程运行在同一个进程当中,共享相同的运行环境。线程有开始顺序执行和结束三个部分。
帮助理解:
1、计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。
2、假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行—个任务。
3、进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。
4、一个车间里,可以有很多工人。他们协同完成一个任务。
5、线程就好比车间里的工人。一个进程可以包括多个线程。
二、thread模块
start_new_thread(function, args kwargs=None)
产生一个新的线程,在新的线程中用指定的参数和可选的kwargs来调用这个函数
注意: 使用这种方法时,一定要加time.sleep(),否则每个线程将可能不执行。此方法还有一个缺点,遇到较复杂的问题时,线程数不易控制。
示例一:测试多线程程序是否在同一时刻运行
python 3 中是 import _thread
#coding=utf-8
import _thread
import time
def fun1():
print ("Hello Word! %s" %time.ctime())
def main():
#测试程序是否在同一时刻运行
_thread.start_new_thread(fun1,())
_thread.start_new_thread(fun1,())
time.sleep(2)#休眠两秒
if __name__=="__main__":
main()
示例二:多线程测试存活的116.211.155.0/24段的主机
#coding=utf-8
import _thread
import time
import subprocess
def ping_check(ip):
result = subprocess.Popen("ping "+ip, stdout=subprocess.PIPE)
result = result.stdout.read().decode('utf-8','ignore')
if '=' in result:
print('%s ip up' %ip)
def main():
for i in range(1,30):
ip = '116.211.155.'+str(i)
_thread.start_new_thread(ping_check,(ip,))
time.sleep(5)
if __name__=="__main__":
main()
三、threading模块
1、Thread类
- 使用threading模块
- 子类化Thread类
解决了线程数可控的问题
2、生产者-消费者问题和Queue模块
- Queue模块( qsize()、empty()、full()、put()、get() )
- 完美搭档:Queue +Thread
解决了生产参数和计算结果时间都不确定的问题
示例一:测试是否是同一时间多线程输输出Hello…
示例二:10个线程请求百度,并输出请求百度网站返回的状态码和请求时间
#coding=utf-8
import threading
import time
import requests
def fun1():
time_start = time.time()
r = requests.get(url='http://www.baidu.com')
times = time.time()-time_start
print('Status:%s---%s---%s'%(r.status_code,times,time.strftime('%H:%M:%S')))
def main():
threads=[]
threads_count = 10
for i in range(threads_count):
t = threading.Thread(target=fun1,args=())
threads.append(t)
for i in range(threads_count):
threads[i].start()
for i in range(threads_count):
threads[i].join()
if __name__=="__main__":
main()
示例三:queue库介绍
>>> import queue
>>> queue = queue.Queue()
>>> for i in range(10):
... queue.put(i)
...
>>> queue.empty()
False
>>> queue.qsize()
10
>>> queue.get()
0
>>> queue.get()
1
>>> queue.get()
2
>>> queue.get()
3
>>> queue.get()
4
>>> queue.get()
5
>>> queue.get()
6
>>> queue.get()
7
依次取出当中的数据
示例四:以10线程从queue库取数
#coding=utf-8
import threading
import queue
class DoRun(threading.Thread):#定义一个类DoRun
def __init__(self,queue):#导入参数queue
threading.Thread.__init__(self)
self._queue = queue
def run(self):
while not self._queue.empty():
ip = self._queue.get()
print(ip)
def main():
threads = []
threads_count = 10
queue1 = queue.Queue()#此处用queue1 = queue.Queue()的话 会报UnboundLocalError,局部变量使用前未初始化
for i in range(1,255):
queue1.put('111.47.226.'+str(i))
for i in range(threads_count):
threads.append(DoRun(queue1))
for i in threads:
i.start()
for i in threads:
i.join()
if __name__=="__main__":
main()