2011-08-04 13 views
25

मैं पीजीजीटीके से पीओजीबीजेक्ट आत्मनिरीक्षण के लिए पहली बार प्रोग्राम को बदलने की प्रक्रिया में हूं और मैंने थ्रेडिंग के साथ रोडब्लॉक मारा है। मेरे पास एक प्रक्रिया है जो पूरा करने में कुछ समय लगता है, इसलिए मैं उस पर प्रगति पट्टी के साथ एक संवाद पॉप अप करता हूं और मैं प्रक्रिया करने के लिए थ्रेड का उपयोग करता हूं और प्रगति पट्टी को अद्यतन करता हूं। यह पीईजीटीके के साथ ठीक काम करता है लेकिन पीईजीओबीजेक्ट में परिवर्तित होने के बाद, मुझे सभी सामान्य अनुचित थ्रेडिंग अजीबता मिलती है: कार्यक्रम लटकता है, लेकिन यह प्रक्रिया के विभिन्न हिस्सों में लटका हुआ लगता है। इसलिए मुझे लगता है कि कुछ बदल गया है लेकिन मैं कर सकता हूं क्या पता नहीं है।क्या पीटीजीबीजेक्ट आत्मनिरीक्षण में जीटीके डब्ल्यू/पायथन में थ्रेडिंग बदल गई है?

यह सरल पीईजीटीके प्रोग्रेसबार उदाहरण है: http://aruiz.typepad.com/siliconisland/2006/04/threads_on_pygt.html जैसा कि उस पृष्ठ पर प्रस्तुत किया गया है, कोड काम करता है। मैं आत्मनिरीक्षण PyGObject करने के लिए इसे परिवर्तित कर दिया है और मैं अपने कार्यक्रम में के रूप में ही समस्याओं मिल: यह लटकी हुई है, यह ठीक से जरूर की सूत्रण क्षमताओं के लिए प्रगति बार, आदि

import threading 
import random, time 
from gi.repository import Gtk, Gdk 
#Initializing the gtk's thread engine 
Gdk.threads_init() 


class FractionSetter(threading.Thread): 
    """This class sets the fraction of the progressbar""" 

    #Thread event, stops the thread if it is set. 
    stopthread = threading.Event() 

    def run(self): 
     """Run method, this is the code that runs while thread is alive.""" 

     #Importing the progressbar widget from the global scope 
     global progressbar 

     #While the stopthread event isn't setted, the thread keeps going on 
     while not self.stopthread.isSet() : 
      # Acquiring the gtk global mutex 
      Gdk.threads_enter() 
      #Setting a random value for the fraction 
      progressbar.set_fraction(random.random()) 
      # Releasing the gtk global mutex 
      Gdk.threads_leave() 

      #Delaying 100ms until the next iteration 
      time.sleep(0.1) 

    def stop(self): 
     """Stop method, sets the event to terminate the thread's main loop""" 
     self.stopthread.set() 

def main_quit(obj): 
    """main_quit function, it stops the thread and the gtk's main loop""" 
    #Importing the fs object from the global scope 
    global fs 
    #Stopping the thread and the gtk's main loop 
    fs.stop() 
    Gtk.main_quit() 

#Gui bootstrap: window and progressbar 
window = Gtk.Window() 
progressbar = Gtk.ProgressBar() 
window.add(progressbar) 
window.show_all() 
#Connecting the 'destroy' event to the main_quit function 
window.connect('destroy', main_quit) 

#Creating and starting the thread 
fs = FractionSetter() 
fs.start() 

Gtk.main() 

प्रलेखन में अद्यतन नहीं है, यह जोर देता है कि gdk_threads_init() चलाने से पहले आपको पहले g_thread_init (NULL) चलाना होगा। लेकिन इसे चलाने के लिए, आपको कुछ अतिरिक्त पुस्तकालयों में लिंक करने की आवश्यकता है। अगर मैं आत्मनिरीक्षण के माध्यम से चिकना आयात करने की कोशिश और उसके बाद मैं GLib.thread_init() चलाने का प्रयास, मैं निम्नलिखित त्रुटि मिलती है:

>>> from gi.repository import GLib 
>>> GLib.thread_init(None) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.7/site-packages/gi/types.py", line 44, in function 
    return info.invoke(*args) 
glib.GError: Could not locate g_thread_init: `g_thread_init': /usr/lib/libglib-2.0.so.0: undefined symbol: g_thread_init 

मुझे लगता है इस वजह से अतिरिक्त सूत्रण पुस्तकालयों लिंक नहीं थे। अगर यह मेरी थ्रेडिंग समस्याओं का कारण है, तो मैं जीएलआईबी के साथ कैसे काम कर सकता हूं जैसे कि उन पुस्तकालयों को जोड़ा गया है?

+1

क्या आपको 'Gdk.threads_enter()' और 'Gdk.threads_leave()' के साथ 'Gtk.main() 'पर कॉल को लपेटना नहीं है? मैंने देखा है कि सभी सी कोड उदाहरण ऐसा करते हैं। उदा। Http://blogs.operationaldynamics.com/andrew/software/gnome-desktop/gtk-thread-awareness –

उत्तर

25

मैंने पाइथन (जीनोम सुडोकू, इस मामले में, जो वास्तव में मुझे दो बार मदद की है) में लिखे गए कुछ जीनोम कार्यक्रमों के माध्यम से अपने स्वयं के प्रश्न का उत्तर देने में कामयाब रहा।

चाल यह है कि आपको अपने कोड की शुरुआत में GObject.threads_init() पर कॉल करना होगा, GLib.thread_init() जैसा कि सी प्रलेखन का तात्पर्य है।

+2

मैं बस धन्यवाद कहना चाहता हूं। मैन, इस सामान के साथ काम करना 90% गुगलिंग है। – miracle2k

+0

बहुत बहुत धन्यवाद! मुझे यह सही समस्या थी और मुझे कोई संकेत नहीं था कि मैं गलत कहां जा रहा था। मेरी इच्छा है कि पीओजीबीजेक्ट के पास "सी डॉक्स की जांच करें" – alldayremix

+1

के बजाय कुछ विशिष्ट दस्तावेज थे, इस उत्तर का एक आधुनिक अपडेट: GObject.threads_init() और GLib.threads_init() समानार्थी हैं और न ही वास्तव में PyGObject v3.10.2 और ऊपर में आवश्यक हैं। यह भी देखें: https://wiki.gnome.org/Projects/PyGObject/Threading –