【问题标题】:Segmentation fault in python?python中的分段错误?
【发布时间】:2020-02-29 22:11:01
【问题描述】:

我正在使用 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_va‌​lidate_onscreen: assertion failed: (priv->onscreen_validated) Aborted (core dumped)

你知道为什么会这样吗?

编辑: 我的代码:

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()

进程.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+ 对象?大多数 GUI 库都不允许这样做。
  • 另外,您是否尝试在没有锁或其他同步的情况下从多个线程访问任何共享的可变对象?由于 GIL,您经常在 Python 中侥幸逃脱,但并非总是如此。而且,除非您真正了解“经常”和“不”的规则,否则您应该始终谨慎行事。
  • 无论如何,如果您想要的不仅仅是模糊的提示,您将不得不向我们展示实际的代码。发布一个SSCCE,其中包含足够的代码来演示问题,然后人们可以阅读它甚至调试它,而不是猜测。
  • 在线程和 GUI 方面总是有点棘手。有时 GUI-Libs 会提供自己的线程...你检查过 gtk3 文档是否有类似的东西?

标签: python multithreading gtk


【解决方案1】:

我已经解决了这个问题。您需要做的是将任何 GTK 调用与任何线程完全分开

出现这些错误是因为仍有一些代码从工作线程(在后台执行我的计算的线程)访问 gtk ui。我需要做的只是使用gobject.idle_add(some_fuction_telling_gtk_what_to_do)

ALL 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() 调用它。

【讨论】:

  • 这个解决方案对我有用,尽管它是在原始帖子发布 7 年后!
【解决方案2】:

也许你必须先这样做:

import gobject
gobject.threads_init()

这能防止它崩溃吗? (查看http://faq.pygtk.org/index.py?req=show&file=faq20.006.htp

【讨论】:

  • 仍然收到Segmentation fault (core dumped)
猜你喜欢
  • 1970-01-01
  • 2013-10-08
  • 1970-01-01
  • 2013-03-30
  • 1970-01-01
  • 2021-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多