2013-11-29 3 views
0

Я довольно новичок в Python-потоке и все еще не могу заставить его работать исправно. Я не понимаю, почему, но потоки выполняются последовательно, а не параллельно.Python threading: второй поток ждет, пока первый не закончит

могли бы вы совет, что неправильно в коде (я упростил его так же, как я могу получить его ближе к примерам, но он не работает, как ожидалось):

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") 

В консольный вывод. Я вижу, что второй поток запускается только после завершения первого. Я попытался сделать потоки daemonic, удалить .join() строки, но все равно не повезло.

ответ

1

Я хочу, чтобы указать на то, что объект threading.Lock и объекты синхронизации состояние они определяют используются с «с утверждением,» потому что они поддерживают протокол управления контекстом:

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

Здесь управление контекстом машины гарантирует, что замок приобретается автоматически будет перед тем блок выполняется и освобождается после завершения блока, независимо от результатов исключения. Таким образом, предлагаемое решение, сделанное Vincent, похоже, затрагивает более сложную проблему, связанную с блокировкой общих общих ресурсов, останавливая любой другой поток, который пытается получить доступ к ресурсу на своих дорожках (фактически, останавливая любой поток который пытается получить тот же замок). Примечания: Threading.Lock имеет два состояния: заблокирован и разблокирован, и создается в состоянии разблокировки. В дальнейшем, например, только один поток может обновлять глобальную переменную «подсчет»:

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) 

Я бы предложить другое решение с использованием многопроцессорной обработки, так как ваши две параллельные функции в основном два отдельных процесса, которые не нуждаются для доступа к общим ресурсам.

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") 
+0

Спасибо, я определенно попробую это. Извините за поздний ответ, не получили никаких уведомлений о новом ответе. –

1

Вы называете свои цели (target=func1()). Вместо этого следующим образом:

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

EDIT: Это, как вы фиксируете ваши отпечатки:

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,)) 
+0

Привет Винсент, Спасибо за этот совет. Я правильно понимаю, что в моем коде эти строки назначения переменных просто вызывают функцию и не создают потоки правильно? –

+0

Только что проверил, и теперь все в порядке! Извините за такой немой вопрос и еще раз спасибо за помощь. –

+0

Аргумент 'target' конструктора' threading.Thread' должен быть функцией. Когда вы выписываете 'func1()', вместо этого вы возвращаете значение функции 'func1'. Кроме того, вы должны заблокировать свои отпечатки, дать мне 30 секунд. Я отредактирую свой пост. – Vincent

Смежные вопросы