线程是CPU分配资源的基本单位。但一个程序开始运行,这个程序就变成了一个进程,而一个进程相当于一个或者多个线程。当没有多线程编程时,一个进程也是一个主线程,但有多线程编程时,一个进程包含多个线程,包括主线程。使用线程可以实现程序的并发。
创建线程
- 用 threading.Thread 直接在线程中运行函数
import time
import threading
def thread_run(name):
print("%s's first thread!!!"% name)
time.sleep(5)
mike = threading.Thread(target=thread_run, args=('Mike', ))
jone = threading.Thread(target=thread_run, args=('jone', ))
mike.start()
jone.start()
- 通过继承 threading.Thread 类 来创建线程
import time
import threading
class mythread(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self)
self.name = name
def run(self):
print("%s's first thread!!!"% self.name)
time.sleep(5)
mike = mythread('mike')
jone = mythread('jone')
mike.start()
jone.start()
属性
name
daemon
当 daemon = False 时,线程不会随主线程退出而退出(默认时,就是 daemon = False)
当 daemon = True 时,当主线程结束,其他子线程就会被强制结束
import time
import threading
def thread_mike_run(name):
time.sleep(1)
print('mike thread is running 1S')
time.sleep(5)
print("%s's first thread!!!"% name)
def thread_jone_run(name):
time.sleep(2)
print("%s's first thread!!!"% name)
mike = threading.Thread(target=thread_mike_run, args=('Mike', ), daemon=True) #设置daemon为True
#mike = threading.Thread(target=thread_mike_run, args=('Mike', ))
jone = threading.Thread(target=thread_jone_run, args=('jone', ))
mike.start()
jone.start()
print('main thread') #由于线程没有join(),所以主线程会先运行;而jone的daemon为false,所以主线程会等待jone线程运行完毕;但是mike的daemon为True,所以主线程不会等待mike线程
执行结果:
main thread
mike thread is running 1S #mike线程只执行了1S的print,5S的为执行就直接退出了
jone's first thread!!!
Thread类的方法
可以通过help(threading.Thread)查看线程实例所有方法
start()
启动一个线程
join([timeout])
等待直到线程终止。即主线程将不会继续运行,而是等待子线程全部终止后才会继续运行
import time
import threading
def thread_run(name):
time.sleep(2)
print("%s's first thread!!!"% name)
mike = threading.Thread(target=thread_run, args=('Mike', ))
jone = threading.Thread(target=thread_run, args=('jone', ))
mike.start()
jone.start()
mike.join() #阻塞子线程mike直到mike线程执行完毕
jone.join() #阻塞子线程jone直到jone线程执行完毕
print('main thread is running!!!')
执行结果:
jone's first thread!!!
Mike's first thread!!!
main thread is running!!!
如果上面列子不执行join(),结果:主线程先执行,然后才会执行子线程mike和jone
import time
import threading
def thread_run(name):
time.sleep(2)
print("%s's first thread!!!"% name)
mike = threading.Thread(target=thread_run, args=('Mike', ))
jone = threading.Thread(target=thread_run, args=('jone', ))
mike.start()
jone.start()
#mike.join() #阻塞子线程mike
#jone.join() #阻塞子线程jone
print('main thread is running!!!')
执行结果:
main thread is running!!!
jone's first thread!!!
Mike's first thread!!!
isAlive=is_alive()
这个方法用于判断线程是否运行。
1.当线程未调用 start()来开启时,isAlive()会返回False
2.但线程已经执行后并结束时,isAlive()也会返回False
getName()
获取当前线程名
setNmae()
设置线程名
isDaemon()
setDaemon()
布尔值,指明这个线程是daemon线程(True)或者不是(False)。这个只能在start()调用之前才能设置否则会抛出RuntimeError异常。因为主线程不是后台线程,因此在主线程中创建的所有子线程默认值都是 False
import time
import threading
def thread_mike_run(name):
time.sleep(1)
print('mike thread is running 1S')
time.sleep(5)
print("%s's first thread!!!"% name)
def thread_jone_run(name):
time.sleep(2)
print("%s's first thread!!!"% name)
mike = threading.Thread(target=thread_mike_run, args=('Mike', ))
jone = threading.Thread(target=thread_jone_run, args=('jone', ))
mike.setDaemon(True) #设置daemon为True
mike.start()
jone.start()
print('main thread') #由于线程没有join(),所以主线程会先运行;而jone的daemon为false,所以主线程会等待jone线程运行完毕;但是mike的daemon为True,所以主线程不会等待mike线程
执行结果:
main thread
mike thread is running 1S
jone's first thread!!!
函数
threading.active_count()
返回当前存活的线程对象的数量;通过计算len(threading.enumerate())长度而来
包含主线程
import threading, time
def run():
thread = threading.current_thread()
print('%s is running...'% thread.getName()) #返回线程名称
time.sleep(10) #休眠10S方便统计存活线程数量
if __name__ == '__main__':
#print('The current number of threads is: %s' % threading.active_count())
for i in range(10):
print('The current number of threads is: %s' % threading.active_count()) #返回当前存活线程数量
thread_alive = threading.Thread(target=run, name='Thread-***%s***' % i)
thread_alive.start()
thread_alive.join()
print('\nThe current number of threads is: %s' % threading.active_count())
print('%s thread is done...'% threading.current_thread().getName())
执行结果:
The current number of threads is: 1
Thread-***0*** is running...
The current number of threads is: 2
Thread-***1*** is running...
The current number of threads is: 3
Thread-***2*** is running...
The current number of threads is: 4
Thread-***3*** is running...
The current number of threads is: 5
Thread-***4*** is running...
The current number of threads is: 6
Thread-***5*** is running...
The current number of threads is: 7
Thread-***6*** is running...
The current number of threads is: 8
Thread-***7*** is running...
The current number of threads is: 9
Thread-***8*** is running...
The current number of threads is: 10
Thread-***9*** is running...
The current number of threads is: 1
MainThread thread is done...
[Finished in 10.1s]
threading.enumerate()
返回当前活动的Thread对象的列表。该列表包括守护线程、由current_thread()创建的虚拟线程以及主线程。排除了已经终止的线程和尚未启动的线程
threading.currentThread = threading.current_thread()
返回当前线程对象
threading.main_thread()
返回主线程对象,类似 threading.current_thread();只不过一个是返回当前线程对象,一个是返回主线程对象
以下函数还没有看
threading.Condition()
工厂函数,返回一个新的条件变量对象。一个条件变量允许一个或多个线程等待,直到另外一个线程通知他们(他们指这些等待状态的线程)
threading.Event()
工厂函数,返回一个新的event对象。event管理可以使用set()方法将其设置为True,使用clear()将其重设置为False,wait()方法则阻塞知道set()将其设置为True
threading.Lock()
工厂函数,返回一个全新的原始锁对象。当一个线程获得锁后,后来的线程想要获得这个锁,需要等到当前线程释放锁
threading.RLock()
工厂函数,获得一个可重入锁。
threading.Semaphore([value])
工厂函数,返回一个新的信号量对象。
class threading.local
class threading.Timer