线程对象:threading.Thread
threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
- traget:该线程要调用的函数
- args:该线程要传入的参数,元组形式,默认为空元组,可以和kwargs一起使用
- kwargs:该线程要传入的参数,字典形式
方法:
sart():开启一个线程,使run()方法在一个线程中被调用
run():主要用去创建子类时重写
join():确保调用该方法的线程执行完之后再执行下一个线程
is_alive():判断该线程是否存活
daemon():判断该线程是否是守护线程。所有在主线程中创建的线程默认都是非守护线程。
补充:
- 守护线程:只有当所有守护线程都结束,python程序才会退出。若python程序退出,那么所有的守护线程都会被终止,从而结束程序
- 非守护线程:当python程序结束时,若还有非守护线程在运行,那么会等到所有非守护线程结束才会退出
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| """ 通过继承threading.Thread的子类创建线程 """ import time import threading
class TestThread(threading.Thread): def __init__(self, para='hi', sleep=3): super().__init__() self.para = para self.sleep = sleep
def run(self): """线程内容""" time.sleep(self.sleep) print(self.para)
def main(): thread_hi = TestThread() thread_hello = TestThread('hello', 1) thread_hi.start() thread_hello.start() print('Main thread has ended!')
if __name__ == '__main__': main()
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| """ 使用join方法阻塞主线程 """ import time import threading
def test_thread(para='hi', sleep=5): """线程运行函数""" time.sleep(sleep) print(para)
def main(): thread_hi = threading.Thread(target=test_thread) thread_hello = threading.Thread(target=test_thread, args=('hello', 1)) thread_hi.start() thread_hello.start() time.sleep(2) print('马上执行join方法了') thread_hi.join() print('线程thread_hi已结束') thread_hello.join() print('Main thread has ended!')
if __name__ == '__main__': main()
|
锁
- 锁只有锁定与非锁定两种状态
- 当一个锁被锁定时,它并不属于某一个线程
- 锁被创建时,处于非锁定状态,使用acquire()方法来锁定锁;一个锁定的锁无法再次获得
- 使用release()来释放一个锁,不只是获得锁的线程可以释放锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| """ 使用锁实现线程同步 """ import time import threading
lock = threading.Lock()
global_resource = [None] * 5
def change_resource(para, sleep): lock.acquire()
global global_resource for i in range(len(global_resource)): global_resource[i] = para time.sleep(sleep) print("修改全局变量为:", global_resource)
lock.release()
def main(): thread_hi = threading.Thread(target=change_resource, args=('hi', 2)) thread_hello = threading.Thread(target=change_resource, args=('hello', 1)) thread_hi.start() thread_hello.start()
if __name__ == '__main__': main()
|
递归锁
- 释放递归锁的操作必须由获得该锁的线程来进行(同一递归等级)
- 同一个线程在释放锁之前再次获得锁不会阻塞该线程,而是将递归等级加一(初始递归等级为1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| """ 在普通锁中可能造成死锁的情况,可以考虑使用递归锁解决 """ import time import threading
rlock_hi = rlock_hello = threading.RLock()
def test_thread_hi(): rlock_hi.acquire() print('线程test_thread_hi获得了锁rlock_hi') time.sleep(2) rlock_hello.acquire() print('线程test_thread_hi获得了锁rlock_hello') rlock_hello.release() rlock_hi.release()
def test_thread_hello(): rlock_hello.acquire() print('线程test_thread_hello获得了锁rlock_hello') time.sleep(2) rlock_hi.acquire() print('线程test_thread_hello获得了锁rlock_hi') rlock_hi.release() rlock_hello.release()
def main(): thread_hi = threading.Thread(target=test_thread_hi) thread_hello = threading.Thread(target=test_thread_hello) thread_hi.start() thread_hello.start()
if __name__ == '__main__': main()
|
条件变量对象
补充:
1 2 3 4 5 6 7 8
| >>> print(True == 1) >>> print(True == 2) >>> print(False == 0) >>> print(False == 2) True False True False
|
threading.Condition(lock=None):一个条件变量对象允许一个或多个线程等待,直到被另一个线程通知
方法:
- wait(timeout=None):释放锁,等待直到被通知或超时,等待的时间内阻塞线程。
- wait_for(predicate,timeout=None):与wait方法类似,等待。这个方法首先调用predicate函数,判断其返回值,若为true,释放锁,并阻塞,待被通知或超时后,调用predicate函数,返回true,则获得锁,不再阻塞;若为false,继续阻塞;若为false,则不会释放锁,程序继续执行。
- notify(n=1):唤醒n个正在等待这个条件变量的线程
- notify_all():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| """ 让一个线程等待,直到另一个线程通知 """ import time import threading
condition_lock = threading.Condition()
PRE = 0
def pre(): print(PRE) return PRE
def test_thread_hi(): condition_lock.acquire()
print('等待线程test_thread_hello的通知') condition_lock.wait_for(pre) print('继续执行')
condition_lock.release()
def test_thread_hello(): time.sleep(1) condition_lock.acquire()
global PRE PRE = 1 print('修改PRE值为1')
print('通知线程test_thread_hi可以准备获取锁了') condition_lock.notify() condition_lock.release() print('你获取锁吧')
def main(): thread_hi = threading.Thread(target=test_thread_hi) thread_hello = threading.Thread(target=test_thread_hello) thread_hi.start() thread_hello.start()
if __name__ == '__main__': main()
|