Re[2]: gtk_потоки_widget`ы
От: a1EXa Россия  
Дата: 26.06.03 08:38
Оценка:
это все я пробовал на red hat linux 9.0 (asplinux-9.0) IDE Anjuta, gtk+-2.0
Неудивительно, что тест на винде не показал такого же "странного" поведения
Там установка текста лейбла из потока работает безотказно, не говоря уже
о возможности SendMessage кому угодно и когда угодно.
Кстать, обнаружилась еще более интересная весч: если сделать паузу 10 секунд
usleep(10000000) то все нормально работает, даже если успеть за эти десять секунд
запустить 100(!) потоков! Все они четко завершаются, без утечек памяти и, главное,
лейбл отображает сообщения всех потоков! Вот дела... Текст прилагаю.
include <gtk/gtk.h>
#include <glib.h>

GtkWidget *p_label;    //указатель обьявлен глобально, так безопасней
#define ARR_LEN 512    //массив int работает как id каждого потока
int g_int_arr[ARR_LEN]; //для удобства

gpointer th_function(gpointer th_index){ //параметр - индекс потока
    gchar new_label_text[32] = {};
    g_print("thread %d sleeps...\n", (int)th_index);
    g_usleep(10000000);    //при таком "глубоком" сне все нормально работает
    g_snprintf(new_label_text, 32, "%p %d\n", p_label, (int)th_index);
    gtk_label_set_text(GTK_LABEL(p_label), new_label_text);
    //g_signal_emit(... g_quark_from_string...); а может, надо слать сигнал
    // а не пытаться из detached потока менять текст лейбла?!
    return 0;
}

static void but_thr_clicked(GtkWidget *widget, gpointer ptr){  //??gpoiner *??
    GThread *th; 
    GError *err = NULL; 
    static int count = 0;
    th = g_thread_create(th_function, (void*)g_int_arr[count++], FALSE, &err);
    if(th == NULL || err != NULL){
        g_warning("fAIled to create new thread, %s\n", err->message);
        g_error_free(err);
    }
}

int main(int argc, gchar **argv){
    GtkWidget *window, *vbox, *button_thr;
    gchar label_text[32] = "";
    int i;  //инициализируем глобальный массив
    for(i=0; i<ARR_LEN; ++i, g_int_arr[i]=i)
    gtk_init(&argc, &argv);
    if( !g_thread_supported() ){
        g_thread_init(NULL);
    }else g_error("g_threads not SUPPorted!");
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_size_request(GTK_WIDGET(window), 200, 150);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    vbox = gtk_vbox_new(FALSE, 0);  //gomogeneous,     
    gtk_container_add(GTK_CONTAINER(window), vbox);
    p_label = gtk_label_new("");
    g_snprintf(label_text, 32, "label address %p", p_label);
    gtk_label_set_text(GTK_LABEL(p_label), label_text);
    gtk_box_pack_start(GTK_BOX(vbox), p_label, TRUE, TRUE, 0);
    button_thr = gtk_button_new_with_label("create thread");    
    gtk_box_pack_start(GTK_BOX(vbox), button_thr, FALSE, FALSE, 0);    
    g_signal_connect(G_OBJECT(button_thr), "clicked",  
                    G_CALLBACK(but_thr_clicked), p_label);
    g_signal_connect(G_OBJECT(window), "destroy", 
                    G_CALLBACK(gtk_main_quit), NULL);
    gtk_widget_show_all(window);
    gtk_main();    
    return 0;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.