Re: How to properly exit a thread?
- From: Paul Davis <pjdavis engineering uiowa edu>
- To: Xiangfei Jia <xjianz gmail com>
- Cc: gtkmm-list gnome org
- Subject: Re: How to properly exit a thread?
- Date: Sun, 14 May 2006 15:35:35 -0500
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() ;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]