现在的CPU都是多核的,但是我们写的程序大部分都是单核的,为了缩短跑特征的时间,学习下python3的多线程。
python提供了两个模块来实现多线程thread 和threading ,thread 有一些缺点,在threading 得到了弥补,所以我们直接学习threading 就可以了。
threading的Thread类是你主要的运行对象。它有很多thread模块里没有的函数。
函数
(1)start()
开始线程的执行
(2)run()
定义线程的功能的函数(一般会被子类重写)
(3)join(timeout=None)
程序挂起,直到线程结束;如果给了timeout,则最多阻塞timeout秒
(4)getName()
返回线程的名字
(5)setName(name)
设置线程的名字
(6)isAlive()
布尔标志,表示这个线程是否还在运行中
(7)isDaemon()
返回线程的daemon标志
(8)setDaemon(daemonic)
把线程的daemon标志设为daemonic(一定要在调用start()函数前调用)
我们就以获取本机时间为例,介绍一下多线程的运行方式,使用threading模块需要继承thread,然后重定义参数,再实现自己想要的功能。
(好多参数例子中都没用到。。。。。。)
#-*- coding : utf-8 -*-
import threading
import time
class myThread(threading.Thread):
#初始化线程,继承Thread
def __init__(self, threadID, count):
threading.Thread.__init__(self)
self.threadID=threadID
self.count=count
#运行线程
def run(self):
print_time(self.threadID,self.count)
print("进程%d结束"%self.threadID)
#具体操作
def print_time(threadID,count):
while(count):
#获取本机当前时间
print("进程%d: %s"%(threadID, time.ctime(time.time())))
count=count-1
def main():
t1=myThread(1,5)
t2=myThread(2,6)
t1.start()
t2.start()
if __name__ == '__main__':
main()
先是重新定义了一个myThread类,里面初始化了线程数据,以及定义了怎么运行线程,print_time就是定义具体操作,main函数创建线程赋值,并开始线程。
附上运行结果
我们可以发现运行没有规律,如果想要有迹可循,这时我们需要考虑到互斥的机制,目前主要用到两种不一样的互斥
(1)一种是锁,把资源锁定,只能一个使用的锁机制,即同步锁
(2)一种是信号量,锁定线程数,限制运行的线程数
(1)先介绍第一种适用于共享资源,不能同时修改资源信息,只能一个一个的使用(比如几个窗口同时卖车票,同时使用票这个共享资源就会出错,我们就需要把资源锁定)
需要添加的代码
#上锁
lock=threading.Lock()
#上锁
lock.acquire()
#线程结束,释放一个线程,以便开始下一个线程
lock.release()
#-*- coding : utf-8 -*-
import threading
import time
#上锁
lock=threading.Lock()
class myThread(threading.Thread):
#初始化线程,继承Thread
def __init__(self, threadID, count):
threading.Thread.__init__(self)
self.threadID=threadID
self.count=count
#运行线程
def run(self):
#上锁
lock.acquire()
print_time(self.threadID,self.count)
#线程结束,释放一个线程,以便开始下一个线程
lock.release()
print("进程%d结束"%self.threadID)
#具体操作
def print_time(threadID,count):
while(count):
#获取本机当前时间
print("进程%d: %s"%(threadID, time.ctime(time.time())))
count=count-1
def main():
t1=myThread(1,5)
t2=myThread(2,5)
t1.start()
t2.start()
if __name__ == '__main__':
main()
结果
(2)第二种,有操作系统基础的应该了解,就是互斥信号量,控制线程数(适用于节省时间,多线程执行程序,资源不用共享,比如多线程爬虫爬取网上资料)
添加代码
#最大线程数
max=8
#信号量,最大线程数
semaphore=threading.Semaphore(max)
#锁定
semaphore.acquire()
#线程结束,释放一个线程,以便开始下一个线程
semaphore.release()
#-*- coding : utf-8 -*-
import threading
import time
#最大线程数
max=8
#信号量,最大线程数
semaphore=threading.Semaphore(max)
class myThread(threading.Thread):
#初始化线程,继承Thread
def __init__(self, threadID, count):
threading.Thread.__init__(self)
self.threadID=threadID
self.count=count
#运行线程
def run(self):
print_time(self.threadID,self.count)
#线程结束,释放一个线程,以便开始下一个线程
semaphore.release()
print("进程%d结束"%self.threadID)
#具体操作
def print_time(threadID,count):
while(count):
#暂停1秒
time.sleep(1)
#获取本机当前时间
print("进程%d: %s"%(threadID, time.ctime(time.time())))
count=count-1
def main():
for i in range(32):
#相当于线程减1,减为0停止,锁定
semaphore.acquire()
#给线程赋初值
t=myThread(i,i)
print("进程%d开始"%i)
t.start()
if __name__ == '__main__':
main()
结果