More questions on threads.



Hi..

I managed to trace down an example using threads & gtk, but doesnot cover
the particular issue I have.
(The gtk-thread.c example at:
  http://mail.gnome.org/archives/gtk-list/1999-October/msg00412.html)

In this example, each thread is allowed to continue undistrubed.. I want
the ability to KILL a thread from a button.

( I need to build an app which runs and external simulator, monitors it
  in a thread, and has the ability to kill both the monitoring thread and 
  external simulation)

I have tried using  

 pthread_kill(no_tid, 1);

to kill off a thread, but only managed to destroy the whole app :-(
(I have tried all coded 0->11 btw).. 

My heavy modified example of the original gtk-thread.c code (with buttons
to try and kill off the treads is attached.


I look forward to your collective wisdom and guidance..

Best regards

/colin.
#include <gtk/gtk.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <gtk/gtk.h>
#include <glib.h>
#include "pthread.h"

#define YES_IT_IS    (1)
#define NO_IT_IS_NOT (0)

pthread_t no_tid, yes_tid;
G_LOCK_DEFINE_STATIC (yes_or_no);
static volatile int yes_or_no = YES_IT_IS;

/**********************/
void
on_kill_thread1_clicked                (GtkButton       *button,
                                        gpointer         user_data)
{
 pthread_kill(no_tid, 1);
}
/**********************/
void
on_kill_thread2_clicked                (GtkButton       *button,
                                        gpointer         user_data)
{
 pthread_kill(yes_tid, 1);
}
/**********************/
typedef struct 
{
  GtkWidget *label;
  int what;
} yes_or_no_args;
/**********************/
void destroy(GtkWidget *widget, gpointer data)
{
  gtk_main_quit();
}
/**********************/
void *argument_thread(void *args)
{
  yes_or_no_args *data = (yes_or_no_args *)args;
  gboolean say_something;

  for(;;)
    {
      /* sleep a while */
      sleep(rand() / (RAND_MAX / 3) + 1);

      /* lock the yes_or_no_variable */
      G_LOCK(yes_or_no);

      /* do we have to say something? */
      say_something = (yes_or_no != data->what);

      if(say_something)
        {
          /* set the variable */
          yes_or_no = data->what;
        }

      /* Unlock the yes_or_no variable */
      G_UNLOCK(yes_or_no);

      if(say_something)
        {
          /* get GTK thread lock */
          gdk_threads_enter(); 

          /* set label text */
          if(data->what == YES_IT_IS)
            gtk_label_set_text(GTK_LABEL(data->label), "O yes, it is!");
          else
            gtk_label_set_text(GTK_LABEL(data->label), "O no, it isn't!");

          /* release GTK thread lock */
           gdk_threads_leave();    
        }
    }

  return(NULL);
}

int
main (int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *vbox1;
  GtkWidget *label;
  guint kill_thread1_key;
  GtkWidget *kill_thread1;
  guint kill_thread2_key;
  GtkWidget *kill_thread2;
  GtkAccelGroup *accel_group;

  yes_or_no_args yes_args, no_args;

  gtk_set_locale ();

  /* init threads */
  g_thread_init(NULL); 

  gtk_init (&argc, &argv);

  /***********************************/
  /* Start to build the main windows */
  accel_group = gtk_accel_group_new ();

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_object_set_data (GTK_OBJECT (window), "window", window);
  gtk_window_set_title (GTK_WINDOW (window), "window");

  vbox1 = gtk_vbox_new (FALSE, 0);
  gtk_widget_ref (vbox1);
  gtk_object_set_data_full (GTK_OBJECT (window), "vbox1", vbox1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (vbox1);
  gtk_container_add (GTK_CONTAINER (window), vbox1);

  label = gtk_label_new ("Nothing yet set...");
  gtk_widget_ref (label);
  gtk_object_set_data_full (GTK_OBJECT (window), "label", label,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (label);
  gtk_box_pack_start (GTK_BOX (vbox1), label, FALSE, FALSE, 0);

  kill_thread1 = gtk_button_new_with_label ("");
  kill_thread1_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (kill_thread1)->child),
                                   "kill_thread1");
  gtk_widget_add_accelerator (kill_thread1, "clicked", accel_group,
                              kill_thread1_key, GDK_MOD1_MASK, 0);
  gtk_widget_ref (kill_thread1);
  gtk_object_set_data_full (GTK_OBJECT (window), "kill_thread1", kill_thread1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (kill_thread1);
  gtk_box_pack_start (GTK_BOX (vbox1), kill_thread1, FALSE, FALSE, 0);

  kill_thread2 = gtk_button_new_with_label ("");
  kill_thread2_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (kill_thread2)->child),
                                   "kill_thread2");
  gtk_widget_add_accelerator (kill_thread2, "clicked", accel_group,
                              kill_thread2_key, GDK_MOD1_MASK, 0);
  gtk_widget_ref (kill_thread2);
  gtk_object_set_data_full (GTK_OBJECT (window), "kill_thread2", kill_thread2,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (kill_thread2);
  gtk_box_pack_start (GTK_BOX (vbox1), kill_thread2, FALSE, FALSE, 0);

  gtk_signal_connect (GTK_OBJECT (kill_thread1), "clicked",
                      GTK_SIGNAL_FUNC (on_kill_thread1_clicked),
                      NULL);
  gtk_signal_connect (GTK_OBJECT (kill_thread2), "clicked",
                      GTK_SIGNAL_FUNC (on_kill_thread2_clicked),
                      NULL);

  gtk_signal_connect(GTK_OBJECT (window), "destroy",
                     GTK_SIGNAL_FUNC(destroy), 
                     NULL);

  gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);

  /***********************************/

  /* create the threads */
  yes_args.label = label;
  yes_args.what = YES_IT_IS;
  pthread_create(&yes_tid, NULL, argument_thread, &yes_args);

  no_args.label = label;
  no_args.what = NO_IT_IS_NOT;
  pthread_create(&no_tid, NULL, argument_thread, &no_args);

  gtk_widget_show (window);

  gdk_threads_enter();
  gtk_main();
  gdk_threads_leave();
  return 0;
}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]