简体   繁体   中英

Segmentation fault in python?

I'm creating GUI using gtk3. So that the GUI and operation works together, I make a thread with this code: threading.Thread(target=function).start() . Without threading, everything works well, but the GUI will be freezed. With threading, this error occured:

The first one is Segmentation fault (core dumped)

The second one is *** glibc detected *** python: double free or corruption (!prev): 0x09154320 ***

The third one is Gtk:ERROR:/build/buildd/gtk+3.0-3.4.2/./gtk/gtktextview.c:3726:gtk_text_view_va‌​lidate_onscreen: assertion failed: (priv->onscreen_validated) Aborted (core dumped)

Do you know why did that happens?

EDIT: my code:

GUI.py

from gi.repository import Gtk, Gdk, GLib
import Process
import gobject
import threading

class gui():
def __init__(self):
    self.window = Gtk.Window()
    self.window.connect('delete-event', Gtk.main_quit)

    self.box = Gtk.Box()
    self.window.add(self.box)

    self.label = Gtk.Label('idle')
    self.box.pack_start(self.label, True, True, 0)

    self.progressbar = Gtk.ProgressBar()
    self.box.pack_start(self.progressbar, True, True, 0)

    self.button = Gtk.Button(label='Start')
    self.button.connect('clicked', self.on_button_clicked)
    self.box.pack_start(self.button, True, True, 0)

    self.window.show_all()

    GLib.threads_init()
    Gdk.threads_init()
    Gdk.threads_enter()
    Gtk.main()
    Gdk.threads_leave()

def working1(self):
   self.label.set_text('working1')
   result = Process.heavyworks1()   
   print result
   self.label.set_text('idle')  

def on_button_clicked(self, widget):
    threading.Thread(target=self.working1).start()

if __name__ == '__main__':
    gui = gui()

桂

Process.py

a = 0 x = 'something'

def heavyworks1():
    #global a
    #doing something
    #doing other thing
    #a = something
    #return result

def heavyworks2(param):
     #doing something
    #doing other thing
    #return result

I've resolved this one. What you need to do is FULLY SEPARATE ANY GTK CALL FROM ANY THREAD .

Those error occured because there were still some code accessing gtk ui from worker thread (thread that doing my calculation in the background). What I need to do is just separate ALL gtk call from thread by using gobject.idle_add(some_fuction_telling_gtk_what_to_do)

This is a sample:

def stop_progress(self):
    self.worker.join()
    self.label.set_text('idle') 

def working_thread(self, num):
    self.textview.set_text(num)
    Process.heavyworks2(num)    
    gobject.idle_add(self.stop_progress)

self.worker = threading.Thread(target=self.working_thread, args=[100000])
self.worker.start()

You see from that code a function that suppose to working in the background ( working_thread(self,num) ) still having a line accessing gtk call ( self.textview.set_text(num) ). Separate that code into a function and call it from your thread using gobject.idle_add(gtk_call_function) .

It's become like this.

def stop_progress(self):
    self.worker.join()
    self.label.set_text('idle') 

def updateTextView(self, num):
    self.textview.set_text(num)     

def working_thread(self, num):
    gobject.idle_add(self.updateTextView, num)
    Process.heavyworks2(num)    
    gobject.idle_add(self.stop_progress)

self.worker = threading.Thread(target=self.working_thread, args=[100000])
self.worker.start()

So, one important point here is don't update gtk ui directly from any thread. Just separate every code accessing gtk into a function and call it by gobject.idle_add() from thread.

Perhaps you have to do this first:

import gobject
gobject.threads_init()

Does that keep it from crashing? (Check out http://faq.pygtk.org/index.py?req=show&file=faq20.006.htp )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM