Python线程处理。锁在for循环中不起作用

时间:2018-09-27 13:32:39

标签: python python-3.x

我是python的新手,我有以下简单代码:

def f(ID, N):
    # global lock
    if ID == 2:
        time.sleep(0.5)
    if ID == 1:
        lock.acquire()
    for i in range(5):
        print(f'{N}: {time.ctime(time.time())} \n')
        print(f"{i}: lock.locked() = {lock.locked()} \n")
        time.sleep(1)
        if i == 2 and ID == 1:
            lock.release()

t = time.time()
class myThread2 (threading.Thread): 
   def __init__(self, threadID, threadname):
      threading.Thread.__init__(self)
      self.threadID = threadID
      self.name = threadname
   def run(self):
       f(self.threadID, self.name)
       print(f'{self.name} finished')

lock = threading.Lock()

# Create new threads objects          
thread1 = myThread2(1, "Thread-1")
thread2 = myThread2(2, "Thread-2")

# Start new Threads
thread1.start()
thread2.start()

for i in range(5):
    print(f'\t\t\t main programm: {time.ctime(time.time())} \n')
    time.sleep(1)

# thread1.join()
# thread2.join()
print(time.time()-t)

输出为:

Thread-1: Thu Sep 27 15:04:29 2018 
             main programm: Thu Sep 27 15:04:29 2018 


0: lock.locked() = True 

Thread-2: Thu Sep 27 15:04:29 2018 

0: lock.locked() = True 

             main programm: Thu Sep 27 15:04:30 2018 
Thread-1: Thu Sep 27 15:04:30 2018 


1: lock.locked() = True 

Thread-2: Thu Sep 27 15:04:31 2018 

1: lock.locked() = True 

             main programm: Thu Sep 27 15:04:31 2018 
Thread-1: Thu Sep 27 15:04:31 2018 


2: lock.locked() = True 

Thread-2: Thu Sep 27 15:04:32 2018 

2: lock.locked() = True 

             main programm: Thu Sep 27 15:04:32 2018 
Thread-1: Thu Sep 27 15:04:32 2018 


3: lock.locked() = False 

Thread-2: Thu Sep 27 15:04:33 2018 

3: lock.locked() = False 

             main programm: Thu Sep 27 15:04:33 2018 
Thread-1: Thu Sep 27 15:04:33 2018 


4: lock.locked() = False 

Thread-2: Thu Sep 27 15:04:34 2018 

4: lock.locked() = False 

5.130102634429932Thread-1 finished

>>> Thread-2 finished   

所以我的问题如下:为什么lock.acquire()不能阻止线程2被执行直到i = 2和f函数中的lock.release()命令执行?我希望它为线程1执行前3个循环,并且仅在该线程2进入for循环之后才执行。但是它们thread2在time.sleep(0.5)之后立即进入for循环。这是为什么?在输出中,thread1使for循环中断后,lock.locked()= True,但它对thread2没有任何影响。错误在哪里,您能帮我吗?

4 个答案:

答案 0 :(得分:0)

import time
from threading import Thread, Lock, current_thread

lock = Lock()

def fu():
    lock.acquire()

    for i in range(5):
        print('Hello from ' + current_thread().name)

        if i == 3:
            lock.release()
            break


t1 = Thread(target=fu, daemon=True)
t2 = Thread(target=fu, daemon=True)

t1.start()
t2.start()

time.sleep(5)

这是您所拥有的简单示例,但是它可以正常工作(除非专门控制哪个线程排在第一位)。

答案 1 :(得分:0)

谢谢。这是代码:

def f(ID, N):
    # global lock
    if ID == 2:
        time.sleep(0.5)
        lock.acquire()
        lock.acquire()
    for i in range(5):
        print(f'{N}: {time.ctime(time.time())} \n')
        print(f"{i}: lock.locked() = {lock.locked()} \n")
        time.sleep(1)
        if i == 2 and lock.locked() == True:
            lock.release()  

有效。在线程1完成i = 2之后,线程2进入for循环。最后,它是lock.locked()= False。所以这就是我想要的结果,我完全不明白它为什么起作用。

答案 2 :(得分:0)

现在仅使用一个锁即可工作。acquire():

def f(ID, N):
    # global lock
    if ID == 2:
        time.sleep(0.5)
    lock.acquire()
    for i in range(5):
        print(f'''{N}:  {time.ctime(time.time())}  
              {i}:  lock.locked() = {lock.locked()}
              current thread = {threading.current_thread()} \n\n''')
        time.sleep(1)
        if i == 2 and lock.locked() == True:
            lock.release()
            print(f'''{N}:  {time.ctime(time.time())}  
            {i}:  lock.locked() = {lock.locked()}
            current thread = {threading.current_thread()} \n\n''')

然后我得到以下输出:

Thread-1:  Thu Sep 27 20:13:52 2018  
              0:  lock.locked() = True
              current thread = <myThread2(Thread-1, started 5880)> 

             main programm: Thu Sep 27 20:13:52 2018 


Thread-1:  Thu Sep 27 20:13:53 2018  
              1:  lock.locked() = True
              current thread = <myThread2(Thread-1, started 5880)> 

             main programm: Thu Sep 27 20:13:53 2018 


Thread-1:  Thu Sep 27 20:13:54 2018  
              2:  lock.locked() = True
              current thread = <myThread2(Thread-1, started 5880)> 

             main programm: Thu Sep 27 20:13:54 2018 


Thread-2:  Thu Sep 27 20:13:55 2018  
              0:  lock.locked() = True
              current thread = <myThread2(Thread-2, started 2004)> 

Thread-1:  Thu Sep 27 20:13:55 2018  
            2:  lock.locked() = False
            current thread = <myThread2(Thread-1, started 5880)> 

             main programm: Thu Sep 27 20:13:55 2018 



Thread-1:  Thu Sep 27 20:13:55 2018  
              3:  lock.locked() = True
              current thread = <myThread2(Thread-1, started 5880)> 


Thread-2:  Thu Sep 27 20:13:56 2018  
              1:  lock.locked() = True
              current thread = <myThread2(Thread-2, started 2004)> 

             main programm: Thu Sep 27 20:13:56 2018 
Thread-1:  Thu Sep 27 20:13:56 2018  
              4:  lock.locked() = True
              current thread = <myThread2(Thread-1, started 5880)> 




Thread-2:  Thu Sep 27 20:13:57 2018  
              2:  lock.locked() = True
              current thread = <myThread2(Thread-2, started 2004)> 

             main programm: Thu Sep 27 20:13:57 2018 
Thread-1 finished


Thread-2:  Thu Sep 27 20:13:58 2018  
            2:  lock.locked() = False
            current thread = <myThread2(Thread-2, started 2004)> 

             main programm: Thu Sep 27 20:13:58 2018 


Thread-2:  Thu Sep 27 20:13:59 2018  
              3:  lock.locked() = False
              current thread = <myThread2(Thread-2, started 2004)> 


Thread-2:  Thu Sep 27 20:14:00 2018  
              4:  lock.locked() = False
              current thread = <myThread2(Thread-2, started 2004)> 


Thread-2 finished
8.259018182754517
lock.locked() = False

它提供了所需的输出,但仍然让我感到困惑。现在线程2在线程1释放它之后获得了锁,那么线程1如何继续与线程2同时运行?我仍然不明白为什么我在问题中写的版本没有给出此输出。

答案 3 :(得分:0)

这是代码:

 public function view(User $user, Survey $survey)
     {
         return false
      }

这是输出:

t = time.time()
def f1(a,b):
    lock2.acquire()
    for i in range(5):
        print(f'\t {i} \t {a+b} \t THREAD1 \t {time.ctime(time.time())} \n')
        time.sleep(1)
    lock2.release()

def f2(a,b):
    lock2.acquire()
    for i in range(5):
        print(f'\t {i**2} \t {a+b} \t THREAD2 \t {time.ctime(time.time())} \n')
        time.sleep(1)
    lock2.release()

class myThread3 (threading.Thread): # create class of threads
   def __init__(self, ID, NAME, f, x, y):
      super().__init__(target = f, name = NAME, args = (x,y,)) # kein self in super()!!!
      # threading.Thread.__init__(self, group=None, target = f, name = NAME, args = (x,y,))
      self.threadID = ID

lock2 = threading.Lock()

# Create new threading.Thread objects         
t1 = myThread3(101, "Threaddd-1", f1, 5, 5)
t2 = myThread3(102, "Threaddd-2", f2, 1, 1)

# Start new Threads
t1.start()
t2.start()

t1.join()
t2.join()

所以我不明白,为什么t1和t2不能同时运行??? t1调用f1而不是f2。 t2调用f2而不是f1。他们不共享变量。所以锁应该没有任何作用,对吧???为什么t2被阻塞直到t1释放锁?