[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
Re: Forking from Gtk
- From: G Hasse <gorhas raditex se>
- To: James Scott Jr <skoona verizon net>
- Cc: gtk-app-devel-list gnome org
- Subject: Re: Forking from Gtk
- Date: Tue, 8 Jul 2008 06:51:18 +0200
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>---
> >
>
--
Göran Hasse
----------------------------------------------------------------
Göran Hasse email: gorhas raditex se Tel: 019-450105
Raditex AB http://www.raditex.se
Planiavägen 15, 1tr Mob: 070-5530148
131 34 NACKA, SWEDEN OrgNr: 556240-0589
VAT: SE556240058901
------------------------------------------------------------------
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]