我在理解Python中的锁时遇到麻烦

时间:2019-10-14 12:26:02

标签: python python-2.7 python-multithreading

我正在玩threading.Lock,并编写了以下测试以加深我的理解。

import threading
from time import sleep

LOCK = threading.Lock()

class Printer(threading.Thread):
    def __init__(self, *args, **kwargs):
        super(Printer, self).__init__(*args, **kwargs)
        self.i = 0

    def run(self):            
        while True:
            print(self.i)
            self.i += 1
            sleep(1)

p = Printer()
p.start()

raw_input() # block main thread until return pressed
LOCK.acquire()

# stop printer for 6 seconds
for _ in range(3):
    print('holding...')
    sleep(2)

# let printer continue
LOCK.release()

我期望以下输出(注释不属于输出):

0
1
2
# user pressed enter
holding...
holding...
holding...
3
4
5
...

但是,打印机不会停止-我得到的实际输出是:

0
1
2
# user pressed enter
holding...
3
4
holding...
5
6
holding...
7
8
...

很显然我在这里误解了什么?如何临时暂停打印机?

1 个答案:

答案 0 :(得分:1)

您还必须获得线程中的锁。锁本身根本不执行任何操作。这样做的唯一目的是使您不能两次获得该锁-从而使代码的两个或更多部分互斥。谁获得了锁,都可以在尝试获取锁的同时执行其他所有线程阻塞。

考虑此版本的代码(我使用的是with,但您也可以用获取/发布代替它。

import threading
from time import sleep

LOCK = threading.Lock()

class Printer(threading.Thread):
    def __init__(self, *args, **kwargs):
        super(Printer, self).__init__(*args, **kwargs)
        self.i = 0

    def run(self):
        while True:
            with LOCK:
                print(self.i)
                self.i += 1
            sleep(1)

p = Printer()
p.start()

raw_input() # block main thread until return pressed
LOCK.acquire()

# stop printer for 6 seconds
for _ in range(3):
    print('holding...')
    sleep(2)

# let printer continue
LOCK.release()

现在可以执行您想要的操作。

这仍然不是“正确的”,因为您的主线程在释放锁定后立即退出。通常,这被认为是不好的编程,但是在演示脚本中,这可能并不重要。您只是不再拥有对线程的任何控制-它会在那里运行直到被信号杀死为止。