[英]Segmentation fault in python?
我正在使用 gtk3 創建 GUI。 為了讓 GUI 和操作一起工作,我用以下代碼創建了一個線程: threading.Thread(target=function).start()
。 沒有線程,一切正常,但 GUI 將被凍結。 使用線程,發生此錯誤:
第一個是Segmentation fault (core dumped)
第二個是*** glibc detected *** python: double free or corruption (!prev): 0x09154320 ***
第三個是Gtk:ERROR:/build/buildd/gtk+3.0-3.4.2/./gtk/gtktextview.c:3726:gtk_text_view_validate_onscreen: assertion failed: (priv->onscreen_validated) Aborted (core dumped)
你知道為什么會這樣嗎?
編輯:我的代碼:
圖形用戶界面
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()
進程.py
a = 0 x = '東西'
def heavyworks1():
#global a
#doing something
#doing other thing
#a = something
#return result
def heavyworks2(param):
#doing something
#doing other thing
#return result
我已經解決了這個問題。 您需要做的是將任何 GTK 調用與任何線程完全分離。
發生這些錯誤是因為仍有一些代碼從工作線程(在后台進行計算的線程)訪問 gtk ui。 我需要做的只是使用gobject.idle_add(some_fuction_telling_gtk_what_to_do)
將所有gtk 調用從線程中分離出來
這是一個示例:
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()
您從該代碼中看到一個假設在后台工作的函數( working_thread(self,num)
)仍然有一行訪問 gtk 調用( self.textview.set_text(num)
)。 將該代碼分成一個函數並使用gobject.idle_add(gtk_call_function)
從您的線程中調用它。
變成了這個樣子。
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()
所以,這里的一個重點是不要直接從任何線程更新 gtk ui。 只需將訪問 gtk 的每個代碼分離到一個函數中,然后從線程中通過gobject.idle_add()
調用它。
也許你必須先這樣做:
import gobject
gobject.threads_init()
這能防止它崩潰嗎? (查看http://faq.pygtk.org/index.py?req=show&file=faq20.006.htp )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.