GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Mon Dec 22, 2014 12:40 am

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: GTK 2 Win32 big memory problem!
PostPosted: Wed Jun 18, 2014 7:05 pm 
Offline
Familiar Face

Joined: Wed Jun 18, 2014 2:14 pm
Posts: 5
Hi,

For my 3D Printer i have write a programm that send the Gcodes to the Printer.
I use the GTK+ 2.24.10 for Win32.
Until yesterday i know all is fine, but now i have seen (in Windowstaskmanager)
the programm needs more and more memory. (100MB per hour additional)

So i have write a little test programm to make the same effekt.
The testprogramm chance a textbox and fill a progressbar.
When you click on "start" you can see the memory grow in the Taskmanager.
I have test this on 3 different PCs and its every the same effect.

I have upload the programm here.

can someone explain me where is my mistake?

(I suspect the problem is just under Windows)

Here is the code:

Code:
#include <stdlib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <pthread.h>
#include <glib.h>
#include <windows.h>


pthread_t TimerThread;
int TimerThreadRun;

struct WidgetStruct
{
GtkWidget   *MainWindow,
            *WindowVbox,
            *StartButton,
            *Textbox,
            *Progressbar;

};

static void *ThreadFunction(struct WidgetStruct *Widgets)
{
    unsigned char Counter = 0;
    unsigned int ProgressValue = 0;
    char Buffer[20] = "";

    while(TimerThreadRun)
    {
        sprintf(Buffer,"%d",Counter);
        gdk_threads_enter();

        gtk_entry_set_text(Widgets->Textbox, Buffer);
        gtk_progress_bar_set_text(Widgets->Progressbar, Buffer);
        gtk_progress_set_value(GTK_PROGRESS(Widgets->Progressbar), ProgressValue);

        gdk_threads_leave();
        Counter++;

        if(Counter==0) //bei überlauf von Counter, ProgressValue++
            ProgressValue++;
            if(ProgressValue>100)
                ProgressValue=0;

        printf("%d\n",Counter);
        Sleep(50);
    }

   return NULL;
}

void cbStartButton(GtkWidget *Button, struct WidgetStruct *Widgets)
{
    if(!TimerThreadRun)
    {
      if(pthread_create( &TimerThread, NULL, &ThreadFunction, Widgets ) != 0)
        {
        printf("Konnte Thread nicht erzeugen\n");
        return EXIT_FAILURE;
        }
        else
        {
        TimerThreadRun = 1;
        printf("SendThread Erzeugt!\n");
        }
    }
    else
    {
        TimerThreadRun = 0;
    }
}

///////////////////////////////////////////////////////

int main(int argc, char** argv)
{


    struct WidgetStruct MainWidgets;

    g_thread_init (NULL);
    gdk_threads_init ();
    gdk_threads_enter ();

    gtk_init(&argc, &argv);

    ////////MainWindow//////////
    MainWidgets.MainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    MainWidgets.WindowVbox = gtk_vbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(MainWidgets.MainWindow), MainWidgets.WindowVbox);

    MainWidgets.Textbox = gtk_entry_new();
    gtk_box_pack_start(GTK_BOX(MainWidgets.WindowVbox), MainWidgets.Textbox,FALSE,FALSE,0);

    MainWidgets.Progressbar = gtk_progress_bar_new();
    gtk_box_pack_start(GTK_BOX(MainWidgets.WindowVbox), MainWidgets.Progressbar,FALSE,FALSE,0);

    MainWidgets.StartButton = gtk_button_new_with_label("Start");
    gtk_box_pack_end(GTK_BOX(MainWidgets.WindowVbox), MainWidgets.StartButton,FALSE,FALSE,0);

    gtk_widget_show_all(MainWidgets.MainWindow);

    ///////Signals Connecting/////////////////
    g_signal_connect(MainWidgets.MainWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    g_signal_connect(MainWidgets.StartButton, "clicked", G_CALLBACK(cbStartButton), &MainWidgets);

    gtk_main();
    gdk_threads_leave ();

    return 0;
}



greetings from germany (sorry for my bad english)

BNR


Attachments:
MemoryTest.rar [52.3 KiB]
Downloaded 7 times
Top
 Profile  
 
 Post subject: Re: GTK 2 Win32 big memory problem!
PostPosted: Thu Jun 19, 2014 6:22 am 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 799
Location: UK
Hello,

I can not see anything directly consuming memory in your test code.

I do see that you have thread problems.

- You are accessing the variable "TimerThreadRun" with out a lock or using Atomic access.

- Under Windows you can not use the GDK global lock to access GTK/GDK from multiple threads. Doing this is only valid under X11 on *nix based systems. By accessing GTK/GDK from multiple threads under Windows will make the library unstable which can be seen as memory increases, crashes or other unexpected behaviour.

Your example code can be re-written using Glib and the timeout signal and would be much simpler. If you need threads to do processing of a potentially long running job then use some form of communication between threads to passing information around.

_________________
E.


Top
 Profile  
 
 Post subject: Re: GTK 2 Win32 big memory problem!
PostPosted: Thu Jun 19, 2014 6:33 am 
Offline
Familiar Face

Joined: Wed Jun 18, 2014 2:14 pm
Posts: 5
Hello,

Thanks for your help.
In my 3D-Printer programm, i need threads to do the serial comunication.
Can you show me a little code example which is the right way to use GTK and threads
under Windows?

greetings

BNR


Top
 Profile  
 
 Post subject: Re: GTK 2 Win32 big memory problem!
PostPosted: Thu Jun 19, 2014 7:30 am 
Offline
Familiar Face

Joined: Wed Jun 18, 2014 2:14 pm
Posts: 5
Now i have test the programm the gtk_timeout funktion.
Its exactly the same effekt :-(


Code:
#include <stdlib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <glib.h>




struct WidgetStruct
{
GtkWidget   *MainWindow,
            *WindowVbox,
            *StartButton,
            *Textbox,
            *Progressbar;

};

int TimerFunction(struct WidgetStruct *Widgets)
{
    static unsigned char Counter = 0;
    static unsigned int ProgressValue = 0;
    static char Buffer[20] = "";


        sprintf(Buffer,"%d",Counter);
        gdk_threads_enter();

        gtk_entry_set_text(Widgets->Textbox, Buffer);
        gtk_progress_bar_set_text(Widgets->Progressbar, Buffer);
        gtk_progress_set_value(GTK_PROGRESS(Widgets->Progressbar), ProgressValue);

        gdk_threads_leave();
        Counter++;

        if(Counter==0) //bei überlauf von Counter, ProgressValue++
            ProgressValue++;
            if(ProgressValue>100)
                ProgressValue=0;

        printf("%d\n",Counter);
        Sleep(50);


   return 1;
}

void cbStartButton(GtkWidget *Button, struct WidgetStruct *Widgets)
{
    gtk_timeout_add( 100, TimerFunction, Widgets );
}

///////////////////////////////////////////////////////

int main(int argc, char** argv)
{


    struct WidgetStruct MainWidgets;

    gtk_init(&argc, &argv);

    ////////MainWindow//////////
    MainWidgets.MainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    MainWidgets.WindowVbox = gtk_vbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(MainWidgets.MainWindow), MainWidgets.WindowVbox);

    MainWidgets.Textbox = gtk_entry_new();
    gtk_box_pack_start(GTK_BOX(MainWidgets.WindowVbox), MainWidgets.Textbox,FALSE,FALSE,0);

    MainWidgets.Progressbar = gtk_progress_bar_new();
    gtk_box_pack_start(GTK_BOX(MainWidgets.WindowVbox), MainWidgets.Progressbar,FALSE,FALSE,0);

    MainWidgets.StartButton = gtk_button_new_with_label("Start");
    gtk_box_pack_end(GTK_BOX(MainWidgets.WindowVbox), MainWidgets.StartButton,FALSE,FALSE,0);

    gtk_widget_show_all(MainWidgets.MainWindow);

    ///////Signals Connecting/////////////////
    g_signal_connect(MainWidgets.MainWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    g_signal_connect(MainWidgets.StartButton, "clicked", G_CALLBACK(cbStartButton), &MainWidgets);

    gtk_main();
    gdk_threads_leave ();

    return 0;
}



greetings
BNR


Top
 Profile  
 
 Post subject: Re: GTK 2 Win32 big memory problem!
PostPosted: Fri Jun 20, 2014 8:47 am 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 799
Location: UK
This is closer to what I would write that code
Code:
#include <stdlib.h>
#include <gtk/gtk.h>
#include <glib.h>

struct WidgetStruct
{
    GtkWidget   *MainWindow,
                *WindowVbox,
                *StartButton,
                *Textbox,
                *Progressbar;

    int         id;
    gboolean    running;
};

static gboolean TimerFunction(gpointer data)
{
    struct WidgetStruct *Widgets = (struct WidgetStruct *) data;
    static unsigned char Counter = 0;
    static unsigned int ProgressValue = 0;
    char Buffer[20];

    sprintf(Buffer,"%d",Counter);

    gtk_entry_set_text(GTK_ENTRY (Widgets->Textbox), Buffer);
    gtk_progress_bar_set_text (GTK_PROGRESS_BAR (Widgets->Progressbar), Buffer);
    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(Widgets->Progressbar), ProgressValue / 100.0);

    Counter++;

    if(Counter==0) //bei überlauf von Counter, ProgressValue++
        ProgressValue++;
        if(ProgressValue>100)
            ProgressValue=0;

    printf("%d\n",Counter);

    return TRUE;
}

void cbStartButton(GtkWidget *Button, struct WidgetStruct *Widgets)
{
    if (!Widgets->running)
    {
        Widgets->running = TRUE;
        Widgets->id = g_timeout_add (100, TimerFunction, Widgets);
    }
    else
    {
        g_source_remove (Widgets->id);
        Widgets->running = FALSE;
    }
}

///////////////////////////////////////////////////////

int main(int argc, char** argv)
{
    struct WidgetStruct MainWidgets;

    gtk_init(&argc, &argv);

    ////////MainWindow//////////
    MainWidgets.MainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    MainWidgets.WindowVbox = gtk_vbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(MainWidgets.MainWindow), MainWidgets.WindowVbox);

    MainWidgets.Textbox = gtk_entry_new();
    gtk_box_pack_start(GTK_BOX(MainWidgets.WindowVbox), MainWidgets.Textbox,FALSE,FALSE,0);

    MainWidgets.Progressbar = gtk_progress_bar_new();
    gtk_box_pack_start(GTK_BOX(MainWidgets.WindowVbox), MainWidgets.Progressbar,FALSE,FALSE,0);

    MainWidgets.StartButton = gtk_button_new_with_label("Start");
    gtk_box_pack_end(GTK_BOX(MainWidgets.WindowVbox), MainWidgets.StartButton,FALSE,FALSE,0);

    gtk_widget_show_all(MainWidgets.MainWindow);

    MainWidgets.running = FALSE;

    ///////Signals Connecting/////////////////
    g_signal_connect(MainWidgets.MainWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    g_signal_connect(MainWidgets.StartButton, "clicked", G_CALLBACK(cbStartButton), &MainWidgets);

    gtk_main();

    return 0;
}

_________________
E.


Top
 Profile  
 
 Post subject: Re: GTK 2 Win32 big memory problem!
PostPosted: Fri Jun 20, 2014 11:15 am 
Offline
Familiar Face

Joined: Wed Jun 18, 2014 2:14 pm
Posts: 5
Hello,

Thanks for you code.
I have run the programm with your code but the result is the same :-(

I have upload a log file of the memory

I suspect the problem is GTK in conjunction with MS Windows...

greetings and thanks for your help

BNR


Attachments:
GTK_Memory_log.rar [7.02 KiB]
Downloaded 6 times
Top
 Profile  
 
 Post subject: Re: GTK 2 Win32 big memory problem!
PostPosted: Sat Jun 28, 2014 6:34 pm 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 799
Location: UK
I have not be able to reproduce your problem, although I am running on a Linux machine.

You many want to debug the application using a proper memory profiler rather than using the TaskManager.

_________________
E.


Top
 Profile  
 
 Post subject: Re: GTK 2 Win32 big memory problem!
PostPosted: Sat Jun 28, 2014 8:31 pm 
Offline
Familiar Face

Joined: Wed Jun 18, 2014 2:14 pm
Posts: 5
The problem will only occurs under MS Windows...


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC


Who is online

Users browsing this forum: Yahoo [Bot] and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group