Когда я пытался реализовать код python для имитации тупика, я столкнулся с некоторыми интересными вопросами:
1) Я использовал следующий код для симуляции тупика.
1 from threading import *
2 import time
3
4
5 def thread_one(lock1, lock2):
6 print("thread 1 is trying to acquire lock 1")
7 lock1.acquire()
8 print("lock1 acquired by thread 1")
9 time.sleep(1)
10 print("thread 1 is trying to acquire lock 2")
11 lock2.acquire()
12
13
14 def thread_two(lock1, lock2):
15 print("thread 2 is trying to acquire lock 2")
16 lock2.acquire()
17 print("lock2 acquired by thread 2")
18 time.sleep(1)
19 print("thread 2 is trying to acquire lock 1")
20 lock1.acquire()
21
22
23 if __name__ == "__main__":
24 lock1 = Lock()
25 lock2 = Lock()
26
27 t1 = Thread(target=thread_one, args=(lock1, lock2))
28 t2 = Thread(target=thread_two, args=(lock1, lock2))
29
30 t1.start()
31 t2.start()
32
33 t1.join()
34 t2.join()
И вот мои выводы:
thread 1 is trying to acquire lock 1
lock1 acquired by thread 1
thread 2 is trying to acquire lock 2
lock2 acquired by thread 2
thread 1 is trying to acquire lock 2
thread 2 is trying to acquire lock 1
(program stuck here)
Пожалуйста, поправьте меня, если я ошибаюсь. Я думаю, что моя симуляция правильная, и два потока застряли на этапе получения 2-го замка.
2) Затем я внес следующие изменения:
10 print("thread 1 is trying to release lock 2")
11 lock2.release()
28 t2 = Thread(target=thread_one, args=(lock1, lock2))
В принципе, я хочу оба экземпляры потоков для запуска той же функции thread_one и в функции tr ie освобождают lock2, который еще не был получен. Затем я получил следующие результаты:
thread 1 is trying to acquire lock 1
lock1 acquired by thread 1
thread 1 is trying to acquire lock 1
thread 1 is trying to release lock 2
Exception in thread Thread-1:
Traceback (most recent call last):
File "/Users/bawang/.pyenv/versions/3.6.5/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/Users/bawang/.pyenv/versions/3.6.5/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "test.py", line 11, in thread_one
lock2.release()
RuntimeError: release unlocked lock
(program stuck here)
Мой вопрос: почему оба потока там зависают (мне нужно дважды нажать ctrl + c, чтобы отменить оба из них)? Я понимаю, что второй поток ожидает освобождения lock1 первым потоком. Однако почему первый поток застревает после создания исключения?
3) Затем я продвинулся немного дальше, внеся следующие изменения:
5 def thread_one(lock1, lock2):
6 print("thread 1 is trying to acquire lock 1")
7 lock1.acquire()
8 print("lock1 acquired by thread 1")
9 time.sleep(1)
10 print("thread 1 is trying to release lock 2")
11 lock2.release()
12
13
14 def thread_two(lock1, lock2):
15 print("thread 2 is trying to acquire lock 2")
16 lock2.acquire()
17 print("lock2 acquired by thread 2")
18 time.sleep(1)
19 print("thread 2 is trying to release lock 1")
20 lock1.release()
27 t1 = Thread(target=thread_one, args=(lock1, lock2))
28 t2 = Thread(target=thread_two, args=(lock1, lock2))
На этот раз я хочу посмотреть, что произойдет, если lock1 & lock2 будут получены одним потоком при освобождении в другом. Вот мои выводы:
thread 1 is trying to acquire lock 1
lock1 acquired by thread 1
thread 2 is trying to acquire lock 2
lock2 acquired by thread 2
thread 1 is trying to release lock 2
thread 2 is trying to release lock 1
(Program completes)
Мой вопрос: почему нет исключений? Я ожидал двух RuntimeError: в этом случае снимите разблокированную блокировку .