关于python多线程,需要知道如下几个点:
- 一般使用threading模块即可,
- 使用threading.current_thread().name 查看当前线程名称
- t.setDaemon(True)表示这是一个守护线程,也就是不重要的线程,主线程结束后守护线程也被结束掉,
不写这句的话,主线程结束后子线程还会继续执行下去 - t.join()表示主线程执行到这一句的时候挂起等待,直到子线程t完成后主线程再往后执行下去,
默认情况
def pt(sec):
time.sleep(sec)
print('{} is running!'.format(threading.current_thread().name))
t=threading.Thread(target=pt, args=(3,))
t.start()
print('main thread end..')
>>main thread end..
Thread-1 is running!
可以看到主线程比子线程早结束,并且主线程结束后子线程还是会执行下去的
守护线程
def pt(sec):
time.sleep(sec)
print('{} is running!'.format(threading.current_thread().name))
t=threading.Thread(target=pt, args=(3,))
t.setDaemon(True)
t.start()
print('main thread end..')
>>main thread end..
设置了守护线程后,主线程完成后子线程也被结束了,子线程没法继续执行下去
使用join
def pt(sec):
time.sleep(sec)
print('{} is running!'.format(threading.current_thread().name))
t=threading.Thread(target=pt, args=(3,))
t.start()
t.join()
print('main thread end..')
>>Thread-1 is running!
main thread end..
join的效果就是,主线程执行到这的时候不会继续往下跑了, 而是等到子线程t完成后再往下跑,在子线程join的情况下,t.setDaemon(True)不再生效。
再考虑一种情况,如果有两个子线程,一个join一个没有,会怎样?
def pt(sec):
time.sleep(sec)
print('{} is running!'.format(threading.current_thread().name))
t=threading.Thread(target=pt, args=(3,))
t2=threading.Thread(target=pt, args=(9,))
t.start()
t2.start()
t.join()
print('main thread end..')
>>Thread-1 is running!
main thread end..
Thread-2 is running!
果然如此,子线程2没有join,所以主线程没有等它就往下跑了,子线程2时最后才输出的。
注意:setDaemon(True)的效果要使用python aa.py 的命令方式执行才能看到,在idle里执行会有问题
锁
如果要一段代码在同一时间只能有一个线程执行,那么可以使用lock.acquire() 和lock.release() 包裹住这段代码
lock=threading.Lock()
def pt():
lock.acquire()
for i in range(5):
print('{} is running! '.format(threading.current_thread().name))
lock.release()
t1=threading.Thread(target=pt)
t2=threading.Thread(target=pt)
t1.start()
t2.start()
print('main thread end...')
>>Thread-1 is running!
Thread-1 is running! main thread end...
Thread-1 is running!
Thread-1 is running!
Thread-1 is running!
Thread-2 is running!
Thread-2 is running!
Thread-2 is running!
Thread-2 is running!
Thread-2 is running!
这样的话线程1和2就不会互相影响,被acquire和release包住的部分,会由一个线程执行完,其他的线程才能执行
网友评论