3

我有 3 个线程,它们当前同时运行。

def f1():
    print "running first thread\n"
    sleep(10)

def f2():
    print "running second thread\n"
    sleep(10)

def f3():
    print "running third thread\n"
    sleep(10)


if __name__ == "__main__":
    thread1 = Thread(target = f1)
    thread2 = Thread(target = f2)
    thread3 = Thread(target = f3)

    try:
        thread1 = Thread(target = f1)
        thread1.start()

        thread2 = Thread(target = f2)
        thread2.start()

        thread3 = Thread(target = f3)   
        thread3.start()

        while(thread1.isAlive() or thread2.isAlive() or thread3.isAlive()): 
            thread1.join()
            thread2.join()
            thread3.join()  
    except (KeyboardInterrupt, SystemExit):
        sys.exit()

如何模拟死锁?另外,我怎样才能让每个线程一个接一个地运行?我还可以列出当前在我的脚本中运行的所有线程吗?还是给他们优先权?

4

3 回答 3

5

如何模拟死锁?

死锁意味着一个或多个线程被阻止取得任何进展,因此您可以使用单个线程来模拟它。只需while True:sleep(10).

在实际情况下,您通常有两个线程同时阻止彼此的进程。例如,也许他们以相反的顺序获取了一对锁,所以线程 1 在获得锁 2 之前不会释放锁 1,但线程 2 在获得锁 1 之前不会释放锁 2。所以,它可能最好通过让两个线程永久阻塞来模拟它。

如果你想实际创建一个死锁,最简单的方法是让线程相互阻塞:add thread2.join()tof1thread1.join()to f2。然后f1不能完成,直到f2做,f2不能完成,直到f1做,所以谁都不能完成。

然而,如果你想创建一个现实的死锁,你几乎肯定会想要使用同步对象threading.Lock来做类似上面描述的两锁场景的事情。

另外,我怎样才能让每个线程一个接一个地运行?

好吧,最简单的方法是首先不使用线程。但如果你真的想要,只需这样做:

thread1.start()
thread1.join()
thread2.start()
thread2.join()
thread3.start()
thread3.join()

我还可以列出当前在我的脚本中运行的所有线程吗?

请参阅threading.enumerate()。除了调试目的,您通常不想使用它;如果您想稍后访问它们(就像您正在做的那样),请在创建线程时跟踪它们。

还是给他们优先权?

正如文档所说:

目前,没有优先级,没有线程组,线程不能被销毁、停止、挂起、恢复或中断。

如果你想要这个,你必须走出去threading,例如,通过 , 等使用原生ctypesAPI win32api

于 2013-01-11T23:13:05.103 回答
1

如何模拟死锁?

import threading
import time

l1=threading.Lock()
l2 = threading.Lock()

def f1(name):
    print('thread',name,'about to lock l1')
    with l1:
        print('thread',name,'has lock l1')
        time.sleep(0.3)
        print('thread',name,'about to lock l2')
        with l2:
            print('thread',name,'run into deadLock,\nthis line will never run')

def f2(name):
    print('thread',name,'about to lock l2')
    with l2:
        print('thread',name,'has lock l2')
        time.sleep(0.3)
        print('thread',name,'about to lock l1')
        with l1:
            print('thread',name,'run into deadLock,\nthis line will never run')

if __name__ == '__main__':
    t1=threading.Thread(target=f1, args=['t1',])
    t2=threading.Thread(target=f2, args=['t2',])

    t1.start()
    t2.start()

输出:

$ python tmpThread.py
thread t1 about to lock l1
thread t2 about to lock l2
thread t1 has lock l1
thread t2 has lock l2
thread t1 about to lock l2
thread t2 about to lock l1
于 2020-08-31T19:18:22.060 回答
0

经典的银行转账僵局示例。

from threading import Lock, Thread

accountone = Lock()
accounttwo = Lock()

def transfer(accountone, accounttwo):
    accountone.acquire()
    accounttwo.acquire()
    print("Transaction done")
    accountone.release()
    accounttwo.release()

def transfer_do(accountone, accounttwo):
    while True:
        transfer(accountone, accounttwo) # send money from first account to second
        transfer(accounttwo, accountone) # send money from second account to first

for x in range(30):
    t = Thread(target=transfer_do, args=(accountone, accounttwo))
    t.start()
于 2021-07-04T20:17:17.923 回答