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