thread模块
python学习-thread模块
由于单线程效率低,python引入了多线程编程
前置知识
进程: 是程序的一次执行,每个进程都有自己的地址空间、内存、数据栈及其他记录运行轨迹的辅助数据。
线程: 所有的线程都运行在同一个进程当中,共享相同的运行环境。线程有开始、顺序执行和结束三个部分。
计算机的核心是CPU,它承担了所有的计算任务,它就像一座工厂,时刻运行着。假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。一个车间里,可以有很多工人。他们协同完成一个任务。线程就好比车间里的工人,一个进程可以包括多个线程。
thread模块对于进程何时退出没有任何控制。当主线程结束时,所有其他线程也都强制结束。不会发出警告或者进行适当的清理。所以引入 锁 的概念
主要方法
_thread.start_new_thread(function,args,kwargs=None) //派生一个新的线程,给定agrs和kwargs来执行function
_thread.allocate_lock() //分配锁对象
_thread.exit() //线程退出
lock.acquire(waitflag=1, timeout=-1) //获取锁对象
lock.locked() //如果获取了锁对象返回true,否则返回false
lock.release() //释放锁
_thread.LockType() //锁对象类型
_thread.get_ident() //获取线程标识符
-thread.TIMEOUT_MAX //lock.acquire的最大时间,超时将引发OverflowError
_thread.interrupt_main() //引发主线程KeyboardInterrupt错误,子线程可以用这个函数来终止主线程
实例
- 多线程
import _thread
from time import sleep
import datetime
def date_time_str():
return datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
def loop_one():
print('++++线程一开始于:',date_time_str())
print('++++线程一休眠4秒')
sleep(4)
print('++++线程一休眠结束,结束于:',date_time_str())
def loop_two():
print('++++线程二开始于:',date_time_str())
print('++++线程二休眠2秒')
sleep(2)
print('++++线程二休眠结束,结束于:',date_time_str())
def main():
print('-----所有线程开始时间:',date_time_str())
_thread.start_new_thread(loop_one,())
_thread.start_new_thread(loop_two,())
sleep(6)
print('------所有线程结束时间:',date_time_str())
if __name__=='__main__':
main()
- 使用锁的多线程
import _thread
from time import sleep, ctime
loops = [4, 2]
def loop(nloop, nsec, lock):
print('start loop', nloop, 'at:', ctime())
sleep(nsec)
print('loop', nloop, 'done at', ctime())
lock.release() #释放锁
def main():
print('starting at:', ctime())
locks = []
for i in range(len(loops)):
lock = _thread.allocate_lock()
lock.acquire() #锁上锁
locks.append(lock) #保存锁
for i in range(len(loops)):
_thread.start_new_thread(loop, (i, loops[i], locks[i]))
for i in range(len(loops)):
while locks[i].locked(): pass #使用忙等待暂停主线程,直到所有的锁都被释放继续主线程,
print('all done at', ctime())
if __name__ == '__main__':
main()
- 多线程ping探测C段网址
import _thread
import time
from subprocess import Popen, PIPE
import sys
def ping_check(ip):
# 执行命令,check.stdout.read() 返回 bytes 数据,需解码为 'gbk'
check = Popen('ping {0} \n'.format(ip), stdin=PIPE, stdout=PIPE, shell=True)
data = check.stdout.read().decode('gbk')
# 检测存活
if 'TTL' in data:
sys.stdout.write('%s is UP \n' % ip)
# print('%s is UP \n' % ip) 几个线程是同时启动,所以输出也是输出在一行
# 系统输出可以换行输出
if __name__ == '__main__':
for i in range(1, 255):
ip = '1.31.128.' + str(i)
_thread.start_new_thread(ping_check, (ip, ))
time.sleep(0.1)