Xiangfei,

Not quite...

I've made a couple changes to your code below. I haven't compiled/tested this at all, but just wanted to describe what you should be doing. I'd recommend adding accessor mutators for FrameNode.

Hope it helps.

Xiangfei Jia wrote:

Hi, Paul:

I'm writing a GUI for monitoring system memory and swap disks. Basically, I created a thread to read the "/proc/meminfo" continueously and put new data into the customised DrawingArea class to plot memory graph every second.

It works like everytime the thread read a new data, the thread will wait until the customised DrawingArea class finished ploting the new data and then signal the thread to read more data.

I haven't used gtkmm for long, and not so clear about how to use gtkmm-wrapped threads. I tried to used your method, still now working. Probably, I didn't use it properly.

I did like this:
try {
Glib::Thread *const read = Glib::Thread::create(sigc::mem_fun(node, &FrameNode::read_new_data), false);
 } catch(Glib::Thread::Exit&) {
   // Just exit from the thread.  The Thread::Exit exception
   // is our sane C++ replacement of g_thread_exit().
 }
 catch(...)
 {
   Glib::exception_handlers_invoke();
 }

This is source code in Glib. You're not supposed to included it in your code.

To make things clear, I attated my source code.

Thanks!!!

Fei

------------------------------------------------------------------------


#ifndef FRAMENODE_H
#define FRAMENODE_H

#include <gtkmm.h>
#include <fstream>
#include "DisplayPlot.h"

class FrameNode : public Gtk::Frame {

public:
   FrameNode(char *);
   ~FrameNode();
   Gtk::HBox hbox_top;
   Gdk::Color temp_;
   DisplayPlot *plot_mem;
   DisplayPlot *plot_swap;

         bool TIME_TO_DIE ;

        Glib::Mutex mutex_;
        Glib::Cond cond_drawing_;

        void read_new_data();
        bool update_plot();

private:
   Gtk::Label *label_mem_total, *label_mem_free, *label_mem_used;
   Gtk::Label *label_swap_total, *label_swap_free;
        bool finished_drawing;
        bool finished_adding_new_data;
        char filename[100];
};

#endif
------------------------------------------------------------------------


#include "FrameNode.h"
#include <libglademm/xml.h>
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <cstdlib>

FrameNode::FrameNode(char *fname) :
   hbox_top(false, 0)
{
         TIME_TO_DIE = false ;

   set_label(" Hostname: Local ");
   //set_shadow_type(Gtk::SHADOW_OUT);
   //set_border_width(10);
   Glib::RefPtr<Gnome::Glade::Xml> refXml = 
Gnome::Glade::Xml::create("./monitor-temp.glade");
   Gtk::EventBox *eventbox;
   refXml->get_widget("eventbox1", eventbox);

        eventbox->reparent(*this);

        //plot mem
        plot_mem = Gtk::manage(new DisplayPlot);
   Gtk::VBox *vbox_plot;
        refXml->get_widget("vbox_plot_mem_container", vbox_plot);
        vbox_plot->pack_start(*plot_mem, Gtk::PACK_SHRINK, 0);

        refXml->get_widget("label_mem_total", label_mem_total);
        refXml->get_widget("label_mem_free", label_mem_free);
        refXml->get_widget("label_mem_used", label_mem_used);

        //plot swap
        plot_swap = Gtk::manage(new DisplayPlot);
        refXml->get_widget("vbox_plot_swap_container", vbox_plot);
        vbox_plot->pack_start(*plot_swap, Gtk::PACK_SHRINK, 0);

        refXml->get_widget("label_swap_total", label_swap_total);
        refXml->get_widget("label_swap_free", label_swap_free);

        strcpy(filename, fname);
        finished_drawing = true;
        finished_adding_new_data = false;
        Glib::signal_timeout().connect(sigc::mem_fun(*this, 
&FrameNode::update_plot), 1000);


}

void FrameNode::read_new_data() {
   using namespace std;

   static int count = 1100000;

        while(1) {

                           bool die ;
                           mutex_.lock() ;
                           die = TIME_TO_DIE ;
                           mutex_.unlock() ;

                           if( die )
                           {
                                 return ;
                            }

                string line;
                string str01, str02;
                unsigned long value_mem_total = 0, value_mem_free = 0, 
value_mem_used = 0;
                unsigned long value_swap_total = 0, value_swap_free = 0;
                ifstream inFile(filename);

                if (inFile) {
                        while (!inFile.eof()) {
                                getline(inFile, line);
                                istringstream inStr(line);
                                inStr >> str01;
                                if (str01.compare("Total") == 0) {
                                  inStr >> str02 >> value_mem_total;
                                } else if (str01.compare("Used") == 0) {
                                  inStr >> str02 >> value_mem_used;
                                } else if (str01.compare("SwapTotal:") == 0) {
                                  inStr >> value_swap_total;
                                } else if (str01.compare("SwapFree:") == 0) {
                                        inStr >> value_swap_free;
                                }
                        }
                        inFile.close();
                } else {

                }

                std::string outBuffer;
                std::ostringstream outStr(outBuffer);

                std::string text;
                //value_mem_total
                outStr << value_mem_total << "KB";
                label_mem_total->set_text(outStr.str());
                //value_mem_free
                value_mem_free = value_mem_total - value_mem_used;
                outStr.str("");
                outStr << value_mem_free << "KB";
                label_mem_free->set_text(outStr.str());
                //value_mem_used
                outStr.str("");
                //used_mem_percentage
                int used_mem_percentage = 
(int)((double)value_mem_used/value_mem_total * 100);
                outStr << used_mem_percentage << "%";
                label_mem_used->set_text(outStr.str());

                //value_swap_total
                outStr.str("");
                outStr << value_swap_total << "KB";
                label_swap_total->set_text(outStr.str());
                //value_swap_free
                outStr.str("");
                outStr << value_swap_free << "KB";
                label_swap_free->set_text(outStr.str());
                //used_swap_percentage
                int value_swap_used = value_swap_total - value_swap_free;
        int used_swap_percentage = 
(int)((double)value_swap_used/value_swap_total * 100);

                //add new data into the plot array
                mutex_.lock();
                if (finished_drawing == false) {
                        cond_drawing_.wait(mutex_);
                }
                plot_mem->add_new_data(used_mem_percentage);
                plot_swap->add_new_data(used_swap_percentage);
                finished_drawing = false;
                finished_adding_new_data = true;
                mutex_.unlock();
                count++;
        }

}


bool FrameNode::update_plot() {


        if (finished_adding_new_data == true) {
                plot_mem->plot_graph();
                plot_swap->plot_graph();
                finished_drawing = true;
                finished_adding_new_data = false;
                cond_drawing_.signal();
        }

        return true;
}


FrameNode::~FrameNode() {

}
------------------------------------------------------------------------



#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <gtkmm.h>
#include "FrameNode.h"
#include <fstream>

class MainWindow : public Gtk::Window {

public:
      MainWindow(char *);
      ~MainWindow();
      FrameNode *node;
protected:
       Gtk::VBox vbox_top;
                Gtk::HBox hbox_top;


};

#endif
------------------------------------------------------------------------



#include "MainWindow.h"
#include <iostream>

MainWindow::MainWindow(char *fname) :
   vbox_top(false, 0),
   hbox_top(false, 0)
{
   node = Gtk::manage(new FrameNode(fname));
   hbox_top.pack_start(*node, Gtk::PACK_SHRINK);
        vbox_top.pack_start(hbox_top, Gtk::PACK_SHRINK);
   add(vbox_top);

//      Glib::Thread *const read = Glib::Thread::create(sigc::mem_fun(node, 
&FrameNode::read_new_data), false);
Glib::Thread *const read = Glib::Thread::create(sigc::mem_fun(node, &FrameNode::read_new_data), true );

Delete this:

        try {
          Glib::Thread *const read = Glib::Thread::create(sigc::mem_fun(node, 
&FrameNode::read_new_data), false);
        } catch(Glib::Thread::Exit&) {
          // Just exit from the thread.  The Thread::Exit exception
          // is our sane C++ replacement of g_thread_exit().
        } catch(...) {
          Glib::exception_handlers_invoke();
        }

to here.

   show_all_children();

}


MainWindow::~MainWindow() {

   node->mutex_.lock() ;
   node->TIME_TO_DIE = true ;
   node->mutex_.unlock() ;

   read->join() ;

}
_______________________________________________
gtkmm-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Reply via email to