Re: Multithreading application



Govinda Parida wrote:
> I was trying to run this program but giving lot of error.
>
> error:
>
> (process:16137): GLib-GObject-CRITICAL **: gtype.c:2240:
> initialization assertion failed, use IA__g_type_init() prior to this
> function
>
> (process:16137): GLib-GObject-CRITICAL **: gtype.c:2240:
> initialization assertion failed, use IA__g_type_init() prior to this
> function
>
> (process:16137): GLib-GObject-CRITICAL **: gtype.c:2240:
> initialization assertion failed, use IA__g_type_init() prior to this
> function
>
> (process:16137): GLib-GObject-CRITICAL **: gtype.c:2240:
> initialization assertion failed, use IA__g_type_init() prior to this
> function
>
> (process:16137): GLib-GObject-CRITICAL **:
> g_type_add_interface_static: assertion `G_TYPE_IS_INSTANTIATABLE
> (instance_type)' failed
>
> (process:16137): GLib-GObject-CRITICAL **: gtype.c:2240:
> initialization assertion failed, use IA__g_type_init() prior to this
> function
>
> (process:16137): GLib-GObject-CRITICAL **: gtype.c:2240:
> initialization assertion failed, use IA__g_type_init() prior to this
> function
>
> (process:16137): GLib-GObject-CRITICAL **: gtype.c:2240:
> initialization assertion failed, use IA__g_type_init() prior to this
> function
> Segmentation fault (core dumped)
>
> My program is:
>
> #include <iostream>
>  #include <queue>
>  #include <glibmm/random.h>
>  #include <glibmm/thread.h>
>  #include <glibmm/timer.h>
> #include "gtkmm.h"
>
> using namespace std;
>
> class NewWindow:public Gtk::Window
> {
>     public:
>     Gtk::VBox vbox;
>     Gtk::Label label;
> NewWindow():label("Swipe the Card")
>     {
>         //maximize();
>         set_default_size(400, 370);
>         add(vbox);
>         vbox.pack_start(label, Gtk::PACK_SHRINK);
>         show_all_children();
>     }
> };
>
>
>  class sample : public sigc::trackable
>  {
>  public:
>  
>     sample();
>    ~sample();
>  
>    void fun1();
>    void fun2();
>  
>
>  private:
>    Glib::Mutex     mutex_;
>    Glib::Cond      cond_push_;
>    Glib::Cond      cond_pop_;
>    std::queue<int> queue_;
>  };
>
>  
>  sample::sample()
>  {}
>  
>  sample::~sample()
>  {}
>  
>  void sample::fun1()
>  {
>     NewWindow *window2;
>     window2 = Gtk::manage(new NewWindow);
>     window2->show_all();     
> }
>  
>  void sample::fun2()
>  {
>    //other application
>  }
>  
>  
>  
>
>
> int main(int, char**)
> {
>    Glib::thread_init();
>  
>    sample ob;
>    
>    Glib::Thread *const t1 = Glib::Thread::create(
>        sigc::mem_fun(ob, &sample::fun1), true);
>  
>   // Glib::Thread *const t2 = Glib::Thread::create(
>       // sigc::mem_fun(ob, &sample::t2), true);
>  
>    t1->join();
>    //t2->join();
>  
>  
>    return 0;
>  }
>
Your main problem for those errors is that in you should call the

    Gtk::Main main(argc, argv);

in your main function before you create windows and stuff.

I've merged the dispatcher example and your code to illustrate how a GUI
program with an additional worker thread works. Its not perfect but hey ...

Its probably best to post replies to the mailing list aswell, since I'm
quite new to Gtkmm and thread programming and someone else might be able
to help you, or point out possible mistakes/misconceptions/other or
better ways to do things. Just hit the 'reply to all' button.

Regards
Niko

--- code ---

#include <iostream>
#include <sstream>
 #include <queue>
 #include <glibmm/random.h>
 #include <glibmm/thread.h>
 #include <glibmm/timer.h>
#include "gtkmm.h"

#define PROGRESS_ITERATIONS 1000

using namespace std;

class ThreadProgress : public sigc::trackable
{
public:
  explicit ThreadProgress();
  virtual ~ThreadProgress();

  void launch();
  void join();

  sigc::signal<void>& signal_finished();
  sigc::signal<void, const Glib::ustring&>& signal_label();

  virtual void reference() const { ++ref_count_; }
  virtual void unreference() const { if (!(--ref_count_)) delete this; }

private:
  Glib::Thread*       thread_;
  unsigned int        progress_;
  Glib::Dispatcher    signal_increment_;
  sigc::signal<void>  signal_finished_;
  sigc::signal<void, const Glib::ustring&>  signal_label_;

  void thread_function(); 
  void progress_increment();

  mutable int ref_count_;
 
};

class NewWindow: public Gtk::Window
{
public:
    NewWindow();
    virtual ~NewWindow();

    Glib::Dispatcher signal_finished;
   
protected:
    Gtk::VBox vbox;
    Gtk::Label label;
   
    Glib::RefPtr<ThreadProgress> progress_;
   
    void launch_threads();
    void signal_finished_handler();   
   
};

ThreadProgress::ThreadProgress()
:
  thread_   (0),
  progress_ (0),
  ref_count_(0)
{
  // Increment the reference count
  reference();
  // Connect to the cross-thread signal.
  signal_increment_.connect(sigc::mem_fun(*this,
&ThreadProgress::progress_increment));
}

ThreadProgress::~ThreadProgress()
{}

void ThreadProgress::launch()
{
  // Create a joinable thread.
  thread_ = Glib::Thread::create(sigc::mem_fun(*this,
&ThreadProgress::thread_function), true);
}

void ThreadProgress::join()
{
  thread_->join();
}

sigc::signal<void>& ThreadProgress::signal_finished()
{
  return signal_finished_;
}

sigc::signal<void, const Glib::ustring&>& ThreadProgress::signal_label()
{
  return signal_label_;
}

void ThreadProgress::progress_increment()
{
    ++progress_;
   
    // put integer in string
    std::ostringstream oss;
    oss << progress_;
    Glib::ustring str(oss.str());
    // inform label about it.
    signal_label_.emit(str);

    if(progress_ >= PROGRESS_ITERATIONS)
        signal_finished_();
}


void ThreadProgress::thread_function()
{
  Glib::Rand rand;
  int usecs = 5000;

  for(int i = 0; i < PROGRESS_ITERATIONS; ++i)
  {
    usecs = rand.get_int_range(std::max(0, usecs - 1000 - i),
std::min(20000, usecs + 1000 + i));
    Glib::usleep(usecs);

    // Tell the main thread to increment the progress value.
    signal_increment_();
  }
}

NewWindow::NewWindow():
    label("0"),
    progress_(new ThreadProgress)
{
    // signals from the thread
    progress_->signal_finished().connect(
        sigc::mem_fun(*this, &NewWindow::signal_finished_handler));
    progress_->signal_label().connect(
        sigc::mem_fun(label, &Gtk::Label::set_label));
       
    // one-shot idle handler to lauch threads
    Glib::signal_idle().connect(
            sigc::bind_return(sigc::mem_fun(*this,
&NewWindow::launch_threads), false));
   
    //maximize();
    set_default_size(400, 370);
    add(vbox);
    vbox.pack_start(label, Gtk::PACK_SHRINK);
    show_all_children();
}  
   
NewWindow::~NewWindow()
{
    // wait for the thread if not finished...
    // ideally we want to make the thread abort prematurely
    // here we just wait
    if(progress_)   
    {
           progress_->join();
           progress_.clear();
    }
}

void NewWindow::launch_threads()
{
    progress_->launch();
}

void NewWindow::signal_finished_handler()
{
    progress_->join();
    progress_.clear();
    label.set_label("finished");
}

int main(int argc, char** argv)
{ 
    Gtk::Main main(argc, argv);
    Glib::thread_init();
 
    NewWindow win;

    Gtk::Main::run(win);
 
    return 0;
}




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]