2012-05-25 19 views
5

Il seguente codice si blocca senza fare nulla in Python 3.2.2 in Linux:Perché il tkinter non funziona bene con il multiprocessing?

import tkinter 
from multiprocessing import Process 

def f(): 
    root = tkinter.Tk() 
    label = tkinter.Label(root) 
    label.pack() 
    root.mainloop() 

p = Process(target=f) 
p.start() 

L'unica informazione che ho trovato su questo problema è issue 5527, in cui si nota che il problema è con tkinter importati prima il processo è biforcato, che può essere risolto importando tkinter all'interno della funzione f e che il problema si verifica in Linux ma non in Solaris.

Qualcuno sa che cosa causa esattamente questo problema e se è intenzionale o verrà risolto? C'è qualche soluzione alternativa oltre all'importazione di tkinter localmente ovunque ne abbia bisogno (che sembra uno stile brutto)? Qualche altro modulo ha problemi simili con il multiprocessing?

+1

-0. Conosci il problema. Sai che è stata presentata una segnalazione di bug. Conosci la soluzione alternativa. L'unica altra importante domanda è "Qualcun altro modulo ha problemi simili con il multiprocessing?", Che sembra un po 'aperto. –

+1

@StevenRumbalski: Non conosco il problema: non ho idea di cosa stia facendo tkinter che non funziona qui o perché dipende dalla piattaforma. Il bug report è stato archiviato oltre 3 anni fa, e non vi è alcun segno che qualcuno sappia perché (o esattamente in quali condizioni) questo accada o come risolverlo. Forse la mia ultima domanda dovrebbe aver letto "ci sono altri moduli di libreria standard che non possono essere importati prima di forking un processo", che è un po 'più specifico. – James

risposta

0

Il mio sospetto è che il problema abbia a che fare con la connessione al server X (di solito un socket). Se questo viene creato prima che il processo sia fork() -ed, il processo figlio eredita questa connessione. Ma se prova a usarlo, il server X si confonde.

Dopo un rapido sguardo al Tkinter.py, sembra che forse chiamare la funzione NoDefaultRoot prima di avviare il processo di potrebbe essere utile. Tutto dipende da quando viene effettuata la connessione al server X.

Altrimenti l'importazione di Tkinter dopo la forcella sembra la strada da percorrere.

0

A partire da settembre 2013, ci sono alcuni commenti aggiuntivi sulla segnalazione di bug che forniscono maggiori informazioni su quale sia il vero problema.

http://bugs.python.org/issue5527#msg194848
http://bugs.python.org/issue5527#msg195480

base a quanto sopra, sto cercando di indovinare qualcosa di simile a quanto segue sta accadendo: Tkinter non è thread-safe, quindi (per qualsiasi motivo) Tkinter vuole sapere quale thread è il filo conduttore . Tkinter presuppone che il thread principale quando viene caricato il modulo Tkinter sia anche il thread principale per l'esecuzione del programma. Quando si esegue il fork o il multiprocesso dopo aver caricato Tkinter, questa ipotesi è infranta. (Ad esempio, dopo un fork, il thread principale ricordato si trova nel genitore, non nel figlio.)

Problemi correlati