Re: More questions on threads.
- From: frankc srv net
- To: gtk-app-devel-list gnome org
- Subject: Re: More questions on threads.
- Date: Mon, 09 Apr 2001 20:20:11 -0600
In this example, each thread is allowed to continue undistrubed.. I want
the ability to KILL a thread from a button.
Have you thought about giving your threads a terminal illness?
Make each gtkmain loop have a function that monitors a semaphore
either by creating your own main loop or attaching a function to
the gtk idle function call. I think the pthread library supports
semaphores last time I played with them.
An example loop might look like this:
while(gtk_main_iteration_do(FALSE) != FALSE)
{
// semaphore checking code
if(semaphore_quit())
break;
}
( 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]