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.

$ 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,


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