Sto tentando di scrivere un'applicazione gtkmm che utilizza il multithreading C++ 11. Tuttavia, continuo a correre nell'errore Fatal IO error 11 (Resource temporarily unavailable) on X server
.Come combattere "Errore IO irreversibile 11 (risorsa temporaneamente non disponibile) su X server" in un'applicazione gtkmm multithread?
Ho diversi oggetti Gtk::Image
sulla mia finestra. Ognuno è nel suo Gtk::EventBox
e periodicamente devo cambiare l'immagine. Per farlo ho creato una classe che contiene la casella dell'evento per il blocco specifico e ha una funzione che rimuove l'immagine precedente, genera quella nuova e la posiziona lì.
Ecco un blocco di codice:
while (lock_flag.test_and_set()) {} // std::atomic_flag lock
// ...
std::cerr << 1;
eventBox->foreach(
[eb = this->eventBox](Gtk::Widget& w)
{
eb->Gtk::Container::remove(w);
}
);
std::cerr << 2;
eventBox->add(*im);
std::cerr << 3;
eventBox->show_all_children();
std::cerr << 4;
// ...
lock_flag.clear();
Quando error 11
verifica alcuni dei numeri non si ottiene stampate a std::cerr
, ma dove il problema accade è diverso ogni volta (ho recentemente osservato che schiantarsi dopo il 12 e dopo il 123). Così arrivo alla conclusione che la risorsa che viene utilizzata da qualche parte non è l'immagine, ma lo eventBox
. Tuttavia, dopo l'inizializzazione del programma, non è accessibile da nessuna parte al di fuori di questa funzione e questa funzione è inclusa nel blocco std::atomic_flag
.
Domande: quale può essere una ragione per tale comportamento? Posso assicurarmi che non accada? O posso prendere questo errore e mi aspetto di recuperare da esso?
Modifiche:
ho tentato
- Ho provato a cambiare da utilizzare
std::thread
-Glib::Threads::Thread
, ma senza alcun risultato, ancora ottenere lo stesso errore. - Dopo aver letto this ho tentato di aggiungere
GDK_SYNCHRONIZE
all'ambiente, questo ha generato l'errore[xcb] Unknown request in queue while dequeuing/[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
. Questo mi ha portato a this post, dopo di che ho tentato di chiamareXInitThreads()
prima di iniziare il nuovo thread (sia tramiteGlib::Threads::Thread
estd::thread
), ma questo non ha fatto nulla di positivo; tranne che una volta per caso il thread ha effettivamente eseguito l'intera funzione (visualizzato '4' sullo schermo), ma poi è comunque riuscito a morire con lo stesso messaggioerror 11
.