D
Dmitry Teslenko
Hello!
I have simple gui gtk app. It has worker thread that populates list
with strings and gtk window with main loop which pops strings
from this list and shows them in TreeView.
Thread runs get_data_from_pcap to populate list with strings.
Gtk app calls update_store() with gobject.timeout_add every second.
If I comment time.sleep() in update_store(),
worker thread never wakes up after his time.sleep().
Why?
Here's runnable example:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import pygtk
pygtk.require('2.0')
import gtk
import gobject
import pcap
import sys
import threading
import time
CONSOLE_ENCODING = 'utf-8'
if sys.platform == 'win32':
CONSOLE_ENCODING = 'cp866'
global_pcap_queue = []
global_pcap_lock = threading.Lock()
global_pcap_stop_event = threading.Event()
class CityGame:
def __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.connect('delete_event', self.delete_event)
window.connect('destroy', self.destroy)
store = gtk.ListStore(gobject.TYPE_STRING)
view = gtk.TreeView(store)
#name
col = gtk.TreeViewColumn('Data')
cell = gtk.CellRendererText()
view.append_column(col)
col.pack_start(cell, True)
col.add_attribute(cell, 'text', 0)
vb = gtk.VBox()
vb.pack_start(view)
window.add(vb)
window.set_size_request(400, 300)
window.show_all()
self.__store = store
def main(self):
gobject.timeout_add(1000, self.update_store)
gtk.main()
def update_store(self):
data = None
global_pcap_lock.acquire()
if len(global_pcap_queue):
data = global_pcap_queue.pop(0)
print 'Update'
global_pcap_lock.release()
time.sleep(0.01)
if data:
self.__store.append([data])
return True
def delete_event(self, widget, event, data = None):
dlg = gtk.MessageDialog(flags = gtk.DIALOG_MODAL, type =
gtk.MESSAGE_QUESTION,
buttons = gtk.BUTTONS_YES_NO,
message_format = 'Are you sure you want to quit?')
dlg.set_title('CityGame')
result = dlg.run()
dlg.destroy()
return (result != gtk.RESPONSE_YES)
def destroy(self, widget, data = None):
gtk.main_quit()
def main(args):
cg = CityGame()
cg.main()
def get_data_from_pcap():
#while True:
while not global_pcap_stop_event.isSet():
global_pcap_lock.acquire()
global_pcap_queue.append(str(time.time()))
print 'Thread'
global_pcap_lock.release()
time.sleep(0.01)
return
if __name__ == '__main__':
global_pcap_stop_event.clear()
pcap_thread = threading.Thread(target = get_data_from_pcap)
pcap_thread.start()
main(sys.argv[1:])
global_pcap_stop_event.set()
pcap_thread.join()
I have simple gui gtk app. It has worker thread that populates list
with strings and gtk window with main loop which pops strings
from this list and shows them in TreeView.
Thread runs get_data_from_pcap to populate list with strings.
Gtk app calls update_store() with gobject.timeout_add every second.
If I comment time.sleep() in update_store(),
worker thread never wakes up after his time.sleep().
Why?
Here's runnable example:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import pygtk
pygtk.require('2.0')
import gtk
import gobject
import pcap
import sys
import threading
import time
CONSOLE_ENCODING = 'utf-8'
if sys.platform == 'win32':
CONSOLE_ENCODING = 'cp866'
global_pcap_queue = []
global_pcap_lock = threading.Lock()
global_pcap_stop_event = threading.Event()
class CityGame:
def __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.connect('delete_event', self.delete_event)
window.connect('destroy', self.destroy)
store = gtk.ListStore(gobject.TYPE_STRING)
view = gtk.TreeView(store)
#name
col = gtk.TreeViewColumn('Data')
cell = gtk.CellRendererText()
view.append_column(col)
col.pack_start(cell, True)
col.add_attribute(cell, 'text', 0)
vb = gtk.VBox()
vb.pack_start(view)
window.add(vb)
window.set_size_request(400, 300)
window.show_all()
self.__store = store
def main(self):
gobject.timeout_add(1000, self.update_store)
gtk.main()
def update_store(self):
data = None
global_pcap_lock.acquire()
if len(global_pcap_queue):
data = global_pcap_queue.pop(0)
print 'Update'
global_pcap_lock.release()
time.sleep(0.01)
if data:
self.__store.append([data])
return True
def delete_event(self, widget, event, data = None):
dlg = gtk.MessageDialog(flags = gtk.DIALOG_MODAL, type =
gtk.MESSAGE_QUESTION,
buttons = gtk.BUTTONS_YES_NO,
message_format = 'Are you sure you want to quit?')
dlg.set_title('CityGame')
result = dlg.run()
dlg.destroy()
return (result != gtk.RESPONSE_YES)
def destroy(self, widget, data = None):
gtk.main_quit()
def main(args):
cg = CityGame()
cg.main()
def get_data_from_pcap():
#while True:
while not global_pcap_stop_event.isSet():
global_pcap_lock.acquire()
global_pcap_queue.append(str(time.time()))
print 'Thread'
global_pcap_lock.release()
time.sleep(0.01)
return
if __name__ == '__main__':
global_pcap_stop_event.clear()
pcap_thread = threading.Thread(target = get_data_from_pcap)
pcap_thread.start()
main(sys.argv[1:])
global_pcap_stop_event.set()
pcap_thread.join()