2013-02-18 14 views
7

Czytam PyMOTW threading postdlaczego nie ma miejsca w przykładzie kodu w Pythonie gwintowania

Pierwszy przykład:

import threading 

def worker(): 
    """thread worker function""" 
    print 'Worker' 
    return 

threads = [] 
for i in range(5): 
    t = threading.Thread(target=worker) 
    threads.append(t) 
    t.start() 

go uruchomić i uzyskać wynik:

Worker 
-Worker 
Worker 
-Worker 
Worker 

Numer - to space, a format będzie różnicą za każdym razem, gdy będzie to Ale nie wiem, dlaczego istnieje space?

Czasami wyświetli również empty line, dlaczego?

+1

Należy zablokować 'sys.stdout' przed pisząc do niego – JBernardo

+0

@JBernardo Jak mogę zablokować' sys.stdout'? –

+0

Nie można zablokować mocnego. Można wykonać blokowanie kooperatywne, tworząc globalny muteks i chwytając go przed każdym wydrukiem. Można również zaimportować rejestrowanie i skonfigurować procedurę obsługi strumieniowej dla portera. Następnie loguj wiadomości zamiast pisać do dużych. Ale nie możesz kontrolować, co mogą zrobić inne moduły, które zaimportujesz. – tdelaney

Odpowiedz

12

Jeśli zbadać kod bajtowy dla instrukcji print, wygląda to tak:

>>> def f(): 
... print "Worker" 
... 
>>> dis.dis(f) 
    2   0 LOAD_CONST    1 ('Worker') 
       3 PRINT_ITEM 
       4 PRINT_NEWLINE 
       5 LOAD_CONST    0 (None) 
       8 RETURN_VALUE 

W rzeczywistości, drukując Kasa wyników w szeregu PRINT_ITEM kodów bajtowych:

>>> def g(): 
... print "Worker", "Hello" 
... 
>>> dis.dis(g) 
    2   0 LOAD_CONST    1 ('Worker') 
       3 PRINT_ITEM 
       4 LOAD_CONST    2 ('Hello') 
       7 PRINT_ITEM 
       8 PRINT_NEWLINE 
       9 LOAD_CONST    0 (None) 
      12 RETURN_VALUE 

Aby wiele elementów zawierało spacje między nimi, obiekt pliku ma flagę o nazwie softspace, która wskazuje, czy spacja ma zostać wyprowadzona przed następnym elementem. Kod dla PRINT_ITEM i PRINT_NEWLINE wygląda mniej więcej tak:

def PRINT_ITEM(f, item): 
    if f.softspace: 
     f.write(' ') 
    f.write(str(item)) 
    f.softspace = True 

def PRINT_NEWLINE(f): 
    f.write('\n') 
    f.softspace = False 

Podczas pisania na standardowe wyjście z wielu wątków jednocześnie, operacje te stają się przeplatany w przypadkowych sposobów. Zamiast więc zmieniać naprzemiennie PRINT_ITEM i PRINT_NEWLINE, możesz mieć dwa PRINT_ITEM w jednym rzędzie. Jeśli tak się stanie, w wyjściowym wyjściu będą dodatkowe spacje, ponieważ dwa elementy PRINT_ITEM i flaga softspace wygenerują dodatkowe miejsce.

+0

Oznacza to, że 'print' nie jest wątkowo bezpieczny ... interesujący. – santiagobasulto

0

spróbować wykorzystać sys.stdout.write ("Pracownik \ n")

+0

Ale dlaczego nie można użyć 'print'? –

Powiązane problemy