On Tue, 2008-07-08 at 23:23 +0200, G Hasse wrote:
> On Tue, Jul 08, 2008 at 01:52:00PM -0400, James Scott Jr wrote:
> > G,
> > 
> > I've seen most of the other responses, and better understand what you
> > are trying to do.  And like others -- fork() is not recommended. 
> 
> I can't belive this... Certanly a forground process must be able to
> start a process that completly detatch from the parent. Gtk or not
> it could not matter. If I fork a Gtk program I migt have a lot of
> GtkWidget pointers that are of no use - but if I bother I should be
> able to free those. The gtk_main loop runs around to find out if
> signals have been emitted. So if I exit this loop no sutch activity
> should be going on.
> 
> I have been doing this on FreeBSD for a long time and I have no
> problem there. 
> 
> The only problem I realy have on Linux is that the forked process
> is marked as <defunct> and probably take a process slot until the
> parent exits. In FreeBSD I don't notice this behaviour.
> 
> The cenario you tell below is not quite applicable since my program
> don't know in advance what should be run. I only need the Gtk program
> to set a lot of parameters and then fire of the process. I klient
> server, socket or pipe solution would just make the solution 
> more complicated. And I don't need to minitor the processes during
> calculation.
> 
> > I had similar problem and resolved it in this codeset.
> > http://gfhcm.sourceforge.net  -- a monitor for the [EMAIL PROTECTED] project
> > 
> > First, like you I needed to start several executables in the background,
> > resolve their identify via pid number, and monitor their cpu utilization
> > and associated artifacts to gage their progress.  
> > 
> > I approached it two ways: with standalone gfhcm, and then in
> > client/server way using gfhcmc & gfhcmd; gfhcmc is the gtk gui and
> > gfhcmd is a glib helper daemon.
> > 
> > For your issue: I suggest g_[a]sync_command_line() as a way to launch a
> > background process from a gtk app.  Then using either ipc Queues, pipes,
> > or sockets to connect to process to echange commands and information.
> > Having a formal daemon will help the issue of starting/stopping the
> > background thread. and Finally a dedicated gui that expects to use an
> > IPC to communication with the process.
> > 
> > Anyway that you would like to proceed - I think we all can offer
> > solutions.  But be clear, I and maybe we think, forking is a bad ideal
> > for GTK program period.

Sorry. I don't se this. What i see is forking from a foreground process
and letting the foreground process still live on is a bad idea on 
*LINUX*. Or...

Göran

Ok, the glib/gtk apis can be used to meet the processing conditions you
describe.  I note that you aware of the increased complexity caused by a
design different from what your accustomed to on BSD. I think those of
us who have done a bit of gtk programming in varied situations, see a
solution that does require more effort and design.

John <jcupitt> stated that he got your code to work on Ubuntu with a few
minor additions. And I presume, using some type of gui toolkit on BSD
you been doing this for a while.  So with John's comment and your
experience, I think you can take it from here and use fork().  

However, if you want to redesign to take full advantage of the resources
and capability of GTK/GLIB and LINUX for the benefit of your users
experience; I got some time and would be willing to help you build a
framework -- just send me code or specs to look at.

The design changes to redo your code are not complicated or burdensome;
just different.  I think the outcome of the rework will be a better
piece of software with greater opportunity to please your users - even
if the user is only you.

James,

> > My website may have something of interest:
> > http://mysite.verizon.net/skoona/id2.html
> > 
> > James,
> > 
> > On Tue, 2008-07-08 at 06:51 +0200, G Hasse wrote:
> > > On Mon, Jul 07, 2008 at 10:58:36PM -0400, James Scott Jr wrote:
> > > > G,
> > > > 
> > > > The basic design decision to use fork() as a way to do work in the
> > > > background flawed.  fork()ing is not practical for gtk program.  While
> > > > fork() has been a valid option for many non-gui programs in the absence
> > > > of threads, either g_thread_create() or pthread_create().  Today it is
> > > > not very useful -- as in stop doing it now!
> > > > 
> > > > Consider instead using a valid multi-threaded implementation like
> > > > g_threads_xxx() for GTK based programs.  Or if full multi-threading is
> > > > not required, look at g_timeout_add() which is a background timer
> > > > routine that can serve as one or more background execution units; neatly
> > > > inside an gtk context.
> > > 
> > > This is not a very practical solution if I want to quit the gtk program
> > > and go home... The example I gave was just an example. I want to create
> > > a process that run for a VERY long time. (a week). And to have the GUI
> > > running allong is not a solution. This process don't need to communicate
> > > with the GUI. And if so I can connect to the process with a socket and
> > > ask for services.
> > > 
> > > > 
> > > > $ devhelp
> > > > $ gtk-demo
> > > > 
> > > > The above two program you be pre-installed on your Linux machine:
> > > > devhelp has the gtk and glib api documentation, and gtk-demo shows you
> > > > many of the gtk/glib features in action.
> > > > 
> > > > Having said the multi-thread phrase, here is another word of caution.
> > > > In GTK only the main or ONE thread can safely interface with GTK api
> > > > calls that change the display.  Using more than one thread to call gtk
> > > > apis at the same time will fail or cause a sigfault.  The context of GTK
> > > > being your front-end to X11 is the source of this
> > > > none-thread-safe-caution; it is in how gtk MUST interact with X that
> > > > placing the multi-thread restriction.  There are elegant work-arounds
> > > > this issue.
> > > > 
> > > > Here is a link to the classic FAQ answer on Multi-threaded GTK programs:
> > > > http://library.gnome.org/devel/gtk-faq/stable/x482.html
> > > > 
> > > > Regards,
> > > > James,
> > > 
> > > Tanks for your answer but I don't thing threads is the solution in my
> > > case.
> > > 
> > > > 
> > > > On Mon, 2008-07-07 at 23:03 +0200, G Hasse wrote:
> > > > > Hello,
> > > > > 
> > > > > I have a small demo app. This works on FreeBSD but I can't
> > > > > get to work on Linux. I know that in Linux setsid will fail
> > > > > if the child has the same session_id as the parent. So on
> > > > > Linux you must fork twice. But it also seems that the parent
> > > > > must do an exit. And I don't want that. The code is not very
> > > > > long - so I include it here.
> > > > > 
> > > > > ---<snipp>---
> > > > > //----------------------------------------------------------------------
> > > > > //
> > > > > //  $Id: GtkFork.c,v 1.2 2008/07/07 20:29:17 gorhas Exp $
> > > > > //
> > > > > //  Experiment to run a thing in background
> > > > > //  This works on FreeBSD but not on Linux...
> > > > > //
> > > > > //  Build with
> > > > > //
> > > > > //  CFLAGS := `pkg-config glib-2.0 --cflags` `pkg-config gtk+-2.0 
> > > > > --cflags`
> > > > > //  LDFLAGS := `pkg-config glib-2.0 --libs` `pkg-config gtk+-2.0 
> > > > > --libs`
> > > > > //
> > > > > //  cc $(CFLAGS) -o GtkFork GtkFork.c $(LDFLAGS)
> > > > > //
> > > > > //----------------------------------------------------------------------
> > > > > 
> > > > > #include <gtk/gtk.h>
> > > > > #include <stdlib.h>
> > > > > #include <stdio.h>
> > > > > #include <time.h>
> > > > > #include <string.h>
> > > > > 
> > > > > //----------------------------------------------------------------------
> > > > > // run_btn_callback
> > > > > //
> > > > > // Try to run something in the background
> > > > > //
> > > > > //----------------------------------------------------------------------
> > > > > static void run_btn_callback (GtkWidget *button, gpointer data)
> > > > > {
> > > > > 
> > > > >    int loops_to_run = 0;
> > > > >    int i = 0;
> > > > >    int pid = -1;
> > > > >    int ret = -1;
> > > > > 
> > > > >    // Skriv ut innehållet på skärmen 
> > > > >    printf("Clicked..\n");
> > > > >    printf("Data was: %s\n", gtk_entry_get_text( data ));
> > > > > 
> > > > >    loops_to_run = atoi( gtk_entry_get_text(data));
> > > > > 
> > > > >    // We dont want to wait very long...
> > > > >    if( loops_to_run > 60 )
> > > > >    {
> > > > >       loops_to_run = 60;
> > > > >       printf("Adjusting to 60 loops...\n");
> > > > >    }
> > > > >    printf("Loops to run: %d\n", loops_to_run );
> > > > > 
> > > > > 
> > > > > 
> > > > >    printf("We make a daemon\n");
> > > > >    if ( ( pid = fork() ) < 0 )
> > > > >    {
> > > > >       // Something went wrong
> > > > >       printf("We could not fork.... just exit");
> > > > >       exit(-1);
> > > > >    }
> > > > >    else if ( pid != 0 )
> > > > >    {
> > > > >       
> > > > >       // This is the parent process
> > > > >       printf("The background process have pid:  %d\n", pid);
> > > > >       return;
> > > > >    }
> > > > > 
> > > > >    // Quit gtk
> > > > >    gtk_main_quit();
> > > > > 
> > > > >    // Become session leader
> > > > >    ret = setsid();
> > > > >    if( ret == -1 )
> > > > >    {
> > > > >       perror("We could not be session leader\n");
> > > > >       exit(-1);
> > > > >    }
> > > > > 
> > > > >    // Set umask for safety
> > > > >    umask(0);
> > > > >    
> > > > >    // Set root dir
> > > > >    chdir("/");
> > > > >   
> > > > >  
> > > > >    for( i = 0; i < loops_to_run; i++ )
> > > > >    {
> > > > >       printf("We are running: %d\n", i );
> > > > >       sleep(1);
> > > > >    } 
> > > > > 
> > > > >    exit(0);
> > > > > 
> > > > > }
> > > > > 
> > > > > //----------------------------------------------------------------------
> > > > > // When we quit
> > > > > //----------------------------------------------------------------------
> > > > > static void quit_callback()
> > > > > {
> > > > >    gtk_main_quit ();
> > > > > }
> > > > > 
> > > > > 
> > > > > //----------------------------------------------------------------------
> > > > > //  main
> > > > > //
> > > > > //  Creates a gtk windows to specify how many loops
> > > > > //  the daemon should run.
> > > > > //
> > > > > //----------------------------------------------------------------------
> > > > > int 
> > > > > main (int argc, char **argv)
> > > > > {
> > > > > 
> > > > >   GtkWidget *mainwin = 0L;
> > > > >   GtkWidget *number_entry = 0L;
> > > > >   GtkWidget *run_btn = 0L;
> > > > >   GtkWidget *vbox = 0L;
> > > > > 
> > > > >   /* Initialize i18n support */
> > > > >   printf("Locale is: %s\n", gtk_set_locale () );
> > > > > 
> > > > >   /* Initialize the widget set */
> > > > >   gtk_init (&argc, &argv);
> > > > > 
> > > > >   /* Create the main window */
> > > > >   mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
> > > > > 
> > > > >   /* Set up our GUI elements */
> > > > >   vbox = gtk_vbox_new (FALSE, 0);
> > > > > 
> > > > >   number_entry = gtk_entry_new();
> > > > > 
> > > > >   run_btn = gtk_button_new_with_label("Just run");
> > > > > 
> > > > >   gtk_container_add (GTK_CONTAINER (mainwin), vbox);
> > > > >   gtk_box_pack_start (GTK_BOX (vbox), number_entry, TRUE, TRUE, 0);
> > > > >   gtk_box_pack_start (GTK_BOX (vbox), run_btn, TRUE, TRUE, 0);
> > > > > 
> > > > >   
> > > > >   // Function to call when main window is destroyed
> > > > >   g_signal_connect (G_OBJECT (mainwin),
> > > > >                   "destroy",
> > > > >                   GTK_SIGNAL_FUNC (quit_callback),
> > > > >                   NULL);
> > > > > 
> > > > >   // Function to call when we click the button
> > > > >   g_signal_connect(GTK_OBJECT(run_btn), "clicked",
> > > > >                    G_CALLBACK(run_btn_callback),
> > > > >                    number_entry);
> > > > > 
> > > > >   /* Show the application window */
> > > > >   gtk_widget_show_all (mainwin);
> > > > > 
> > > > >   /* Enter the main event loop, and wait for user interaction */
> > > > >   gtk_main ();
> > > > > 
> > > > >   /* The user lost interest */
> > > > >   return 0;
> > > > > 
> > > > > }
> > > > > 
> > > > > //------------------------------------------------------------------
> > > > > // END
> > > > > //------------------------------------------------------------------
> > > > > 
> > > > > ---<snipp>---
> > > > > 
> > > > 
> > > 
> > 
> 

_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Reply via email to