Re: Sending slots to main thread (implemented)
- From: Joaquim Duran <joaquinduran adtelecom es>
- To: gtkmm-list <gtkmm-list gnome org>
- Subject: Re: Sending slots to main thread (implemented)
- Date: Thu, 30 Aug 2007 18:07:08 +0200
En/na Joaquim Duran ha escrit:
>
> Continuing with the discussion: I've downloaded the glibmm source code.
> I've seen that the Thread Pool implements the SlotList, but privately.
>
> IMO, I think that the SlotList object should be made public mainly for
> two reasons:
>
> - It could help to implement the command patern in Glibmm: an action
> could be seen as a list of slots to be excecuted. Even, the object that
> fills the list of slots, could be different that the object which will
> execute them.
>
> - This is pretty easy to create an object to send arbitrary slots to
> main thread (like thread pool). Pseudocode:
>
> class dispatchslots:
>
> ListStot __list;
> Dispatcher __dispt;
>
> void push(slot) // Executed by working thread
> {
> __list.push(slot);
> __dispt.emit();
> }
>
> void run_slot() // Exceuted by main thread (connected to dispatcher)
> {
> slot = __list.top();
> __list.pop();
> slot.execute();
> }
>
>
>
> What do you think about that?
>
> Thanks and Best Regards,
> Joaquim Duran
> _______________________________________________
> gtkmm-list mailing list
> gtkmm-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtkmm-list
>
>
I've done the implementation and it works fine: I'm able to send a slot
created at runtime to main thread.
I've attached the source code to this e-mail to check it. I think that
implement a class like this one in glibmm will simplify the task of
thread programming.
One problem: to link the object file with the libraries, I've used the
following command in the makefile:
g++ -Wall `pkg-config --libs gtkmm-2.4` `pkg-config --libs gthread-2.0`
-o slots $(OBJECTS)
Why the libraries for thread management are placed in a different .pc
file? is this a bug?
Joaquim Duran
Thanks and Best Regards,
#include <gtkmm/window.h>
#include <gtkmm/main.h>
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <glibmm/dispatcher.h>
#include <glibmm/threadpool.h>
#include <glibmm/thread.h>
#include <iostream>
#include <sstream>
#include <queue>
#include <deque>
// SLOT DISPATCHER
class SlotDispatcher
{
public:
typedef std::queue<sigc::slot<void> > QueueSlot;
SlotDispatcher();
~SlotDispatcher();
void push(const sigc::slot<void>& slot);
protected:
sigc::slot<void> pop();
void run();
private:
Glib::Mutex mutex;
Glib::Dispatcher dispatch;
QueueSlot qslot;
};
SlotDispatcher::SlotDispatcher():
mutex(), dispatch(), qslot()
{
dispatch.connect(sigc::mem_fun(*this, &SlotDispatcher::run));
}
SlotDispatcher::~SlotDispatcher()
{
}
void SlotDispatcher::push(const sigc::slot<void>& slot)
{
{
Glib::Mutex::Lock lock (this->mutex);
qslot.push(slot);
}
dispatch.emit();
}
sigc::slot<void> SlotDispatcher::pop()
{
sigc::slot<void> slot;
Glib::Mutex::Lock lock (this->mutex);
slot = qslot.front();
qslot.pop();
return slot;
}
void SlotDispatcher::run()
{
sigc::slot<void> slot = pop();
slot();
}
// THREAD_WINDOW
class ThreadWindow : public Gtk::Window
{
public:
ThreadWindow();
virtual ~ThreadWindow();
protected:
void timer_work();
void pool_work(long int value);
void main_work(long int value);
private:
Gtk::VBox vbox;
Gtk::Button button;
Gtk::Label label;
sigc::connection conn;
Glib::ThreadPool pool;
SlotDispatcher slotDispt;
Glib::Mutex screen;
};
ThreadWindow::ThreadWindow():
Gtk::Window(), vbox(), label(),
conn(), pool(3, true), slotDispt(), screen()
{
// Windows
add(vbox);
vbox.add(button);
vbox.add(label);
button.set_label("Quit");
button.signal_clicked().connect( sigc::mem_fun(*this,
&ThreadWindow::hide));
show_all_children();
// Threads
conn = Glib::signal_timeout().connect(
sigc::bind_return(
sigc::mem_fun(*this, &ThreadWindow::timer_work),
true), 3000);
}
ThreadWindow::~ThreadWindow()
{
conn.disconnect();
}
void ThreadWindow::timer_work()
{
int value = random();
sigc::slot<void> slot = sigc::bind(
sigc::mem_fun(*this, &ThreadWindow::pool_work), value);
{
Glib::Mutex::Lock lock(this->screen);
std::cout << "Timer_work" << std::endl;
std::cout << "\tValue: " << value << std::endl;
}
pool.push(slot);
}
void ThreadWindow::pool_work(long int value)
{
{
Glib::Mutex::Lock lock(this->screen);
std::cout << "Pool work" << std::endl;
std::cout << "\tValue: " << value << std::endl;
}
slotDispt.push(sigc::bind(
sigc::mem_fun(*this, &ThreadWindow::main_work), value));
}
void ThreadWindow::main_work(long int value)
{
{
Glib::Mutex::Lock lock(this->screen);
std::cout << "Main work" << std::endl;
std::cout << "\tValue: " << value << std::endl;
}
std::stringstream strm;
strm << value;
label.set_label(strm.str());
}
// MAIN
int main(int argc, char *argv[])
{
Glib::thread_init();
Gtk::Main kit(argc, argv);
ThreadWindow mainWin;
Gtk::Main::run(mainWin);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]