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.
Należy zablokować 'sys.stdout' przed pisząc do niego – JBernardo
@JBernardo Jak mogę zablokować' sys.stdout'? –
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