简体   繁体   English

Python线程:第二个线程等到第一个线程完成

[英]Python threading: second thread waits until the first one finishes

I'm quite new to Python threading, and still can't make it working properly. 我对Python线程很陌生,但仍无法使其正常工作。 I do not understand why, but threads are executed consequently and not in a parallel. 我不明白为什么,但线程因此而不是并行执行。

Could you please advice, what is incorrect in the code (I simplified it as much as I can to get it closer to the examples, but it doesn't work as expected): 请问建议,代码中的错误是什么(我尽可能简化它以使其更接近示例,但它不能按预期工作):

import threading, time

def func1():
    for j in range (0, 10):
        print(str(time.ctime(time.time())) + " 1")
        time.sleep(0.5)


def func2():
    for j in range (0, 10):
        print(str(time.ctime(time.time())) + " 2")
        time.sleep(0.5)

print(str(time.ctime(time.time())) + " script started")

t1 = threading.Thread(target = func1(), name = " 1")
t2 = threading.Thread(target = func2(), name = " 2")

t1.start()
t2.start()

t1.join()
t2.join()

print (str(time.ctime(time.time())) + " over")

In console output I see that the second thread only starts when the first one is finished. 在控制台输出中,我看到第二个线程仅在第一个线程完成时才启动。 I've tried to make threads daemonic, remove .join() lines, but still no luck. 我试图使线程守护,删除.join()行,但仍然没有运气。

You're calling your targets ( target=func1() ). 你正在调用你的目标( target=func1() )。 Instead do as follows: 而是做如下:

t1 = threading.Thread(target=func1, name = "1")
t2 = threading.Thread(target=func2, name = "2")

EDIT: This is how you lock your prints : 编辑:这是你锁定你的印刷品的方式:

import threading, time

def func1(lock):
    for j in range (10):
        with lock:
            print(str(time.ctime(time.time())) + " 1")
        time.sleep(0.5)


def func2(lock):
    for j in range (10):
        with lock:
            print(str(time.ctime(time.time())) + " 2")
        time.sleep(0.5)

lock = threading.Lock()
t1 = threading.Thread(target = func1, name = " 1", args=(lock,))
t2 = threading.Thread(target = func2, name = " 2", args=(lock,))

I want to indicate the fact that a threading.Lock object and condition synchronization objects they define are used with the "with statement," because they support the context management protocol: 我想指出一个事实,即他们定义的threading.Lock对象和条件同步对象与“with语句”一起使用,因为它们支持上下文管理协议:

lock = threading.Lock() # After: import threading
with lock:
    # critical section of code
    ...access shared resources...

Here, the context management machinery guarantees that the lock is automatically acquired before the block is executed and released once the block is complete, regardless of exception outcomes. 这里,上下文管理机制保证在块执行之前自动获取锁,并在块完成后释放,而不管异常结果如何。 Therefore, the suggested solution above by Vincent seems to be addressing a more complex problem, one that deals with placing a lock on shared common resources, stopping any other thread that tries to access the resource in its tracks (in fact, stopping any thread that attempts to acquire the same lock). 因此,Vincent上面提出的建议解决方案似乎正在解决一个更复杂的问题,即处理对共享公共资源的锁定,停止尝试访问其资源的任何其他线程(事实上,停止任何线程)试图获得相同的锁)。 Notes: A threading.Lock has two states: locked and unlocked, and it is created in the unlocked state. 注意:threading.Lock有两种状态:锁定和解锁,并在解锁状态下创建。 In the following, for example, as only one thread can update the global variable "count": 例如,在下文中,因为只有一个线程可以更新全局变量“count”:

import threading, time
count = 0
def adder(addlock): # shared lock object passed in
    global count
    with addlock:
        count = count + 1 # auto acquire/release around stmt
    time.sleep(0.5)
    with addlock:
        count = count + 1 # only 1 thread updating at any time
addlock = threading.Lock()
threads = []
for i in range(100):
    thread = threading.Thread(target=adder, args=(addlock,))
    thread.start()
    threads.append(thread)
for thread in threads: thread.join()
print(count)

I'd suggest another solution using multiprocessing since your two parallel functions are basically two separate processes that don't need to access any shared resources. 我建议使用多处理的另一种解决方案,因为您的两个并行功能基本上是两个不需要访问任何共享资源的独立进程。

from multiprocessing import Process
import time

def func1():
    for j in range (0, 10):
        print(str(time.ctime(time.time())) + " 1")
        time.sleep(0.5)

def func2():
    for j in range (0, 10):
        print(str(time.ctime(time.time())) + " 2")
        time.sleep(0.5)

if __name__ == '__main__':
    print(str(time.ctime(time.time())) + " script started")
    p1 = Process(target=func1)
    p1.start()
    p2 = Process(target=func2)
    p2.start()
    p1.join()
    p2.join()
    print (str(time.ctime(time.time())) + " over")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM