C程序作为守护进程在后台运行,仅在需要时生成Gtk窗口

C程序作为守护进程在后台运行,仅在需要时生成Gtk窗口,c,multithreading,gtk,C,Multithreading,Gtk,我用C编写了一个守护进程,用于轮询服务器的布尔值。如果为true,它什么也不做,如果为false,我希望它生成一个用户可以交互的Gtk窗口 我的main(…)函数生成一个轮询服务器的线程,我已经使用pthread实现了这个线程。我希望main(…)函数也生成第二个线程,它将打开一个Gtk窗口。我的问题是,我一次只能打开一个窗口,就像我在一个简单的测试程序中实现的那样: #include <stdio.h> #include <unistd.h> #include <

我用C编写了一个守护进程,用于轮询服务器的布尔值。如果为true,它什么也不做,如果为false,我希望它生成一个用户可以交互的Gtk窗口

我的main(…)函数生成一个轮询服务器的线程,我已经使用pthread实现了这个线程。我希望main(…)函数也生成第二个线程,它将打开一个Gtk窗口。我的问题是,我一次只能打开一个窗口,就像我在一个简单的测试程序中实现的那样:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <gtk/gtk.h>
#include <stdbool.h>

#define PROG_NAME "org.lwtw.laut-server"

static void ack (GtkApplication *app, gpointer user_data)
{
    printf("Acknowledged!\n");
}

static void alarm_dialog (GtkApplication *app)
{
    GtkWidget *win;
    GtkWidget *ack_btn;
    GtkWidget *box;
    GtkWidget *btn_box;
    GtkWidget *label;
    GtkWidget *icon;

    win = gtk_application_window_new(app);
    gtk_window_set_title(GTK_WINDOW(win), "Laut Server");
    gtk_window_set_default_size(GTK_WINDOW(win), 300, 200);

    box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
    gtk_container_add(GTK_CONTAINER(win), box);

    icon = gtk_image_new_from_icon_name("insync-error", GTK_ICON_SIZE_DIALOG);
    gtk_box_pack_start(GTK_BOX(box), icon, true, true, 5);

    label = gtk_label_new("An alarm signal was received");
    gtk_box_pack_start(GTK_BOX(box), label, true, true, 5);

    btn_box = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
    gtk_box_pack_start(GTK_BOX(box), btn_box, true, true, 5);

    ack_btn = gtk_button_new_with_label("Acknowledge Signal");
    g_signal_connect(ack_btn, "clicked", G_CALLBACK(ack), NULL);
    g_signal_connect_swapped(ack_btn, "clicked", G_CALLBACK(gtk_widget_destroy), win);
    gtk_container_add(GTK_CONTAINER(btn_box), ack_btn);

    gtk_widget_show_all(win);
}

static void activate (GtkApplication *app, gpointer user_data)
{
    alarm_dialog(app);
}

void gui_main (void *data)
{
    GtkApplication *app;

    app = gtk_application_new(PROG_NAME, G_APPLICATION_FLAGS_NONE);
    g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
    g_application_run(G_APPLICATION(app), 0, NULL);
    g_object_unref(app);
}

int main (int argc, char **argv)
{
    while (getc(stdin) != 'q') {
        pthread_t d_thread;
        pthread_create(&d_thread, NULL, (void *) gui_main, NULL);
    }

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#定义程序名“org.lwtw.laut服务器”
静态无效确认(GTK应用程序*应用程序、gpointer用户数据)
{
printf(“已确认!\n”);
}
静态无效报警对话框(GTK应用程序*应用程序)
{
GtkWidget*赢;
GtkWidget*确认btn;
GtkWidget*框;
GtkWidget*btn_盒;
GtkWidget*标签;
GtkWidget*图标;
win=gtk_应用程序_窗口_新(应用程序);
gtk_窗口设置标题(gtk_窗口(win),“Laut服务器”);
gtk_窗口设置默认大小(gtk_窗口(win),300,200);
长方体=gtk_长方体_新(gtk_方向_垂直,10);
gtk_容器添加(gtk_容器(win),盒子);
icon=gtk_image_new_from_icon_name(“同步错误”,gtk_icon_SIZE_对话框);
gtk_-box_-pack_启动(gtk_-box(box),图标,真,真,5);
label=gtk_label_new(“收到报警信号”);
gtk_盒包装开始(gtk_盒(盒),标签,正确,正确,5);
btn_盒=gtk_按钮_盒_新(gtk_方向_水平);
gtk_-box_-pack_-start(gtk_-box(box),btn_-box,真,真,5);
ack_btn=gtk_按钮_新_,带有标签(“确认信号”);
g_信号连接(确认btn,“点击”,g_回拨(确认),空);
g_信号连接交换(确认btn,“点击”,g_回调(gtk_小部件销毁),赢);
gtk_容器添加(gtk_容器(btn_盒),确认btn);
gtk_widget_show_all(赢);
}
静态无效激活(GTK应用程序*应用程序、gpointer用户数据)
{
报警对话框(app);
}
void gui_main(void*数据)
{
GTK应用程序*app;
app=gtk_应用程序_新(程序名称,G_应用程序标志_无);
g_信号连接(应用程序,“激活”,g_回调(激活),空);
g_应用程序运行(g_应用程序(应用程序),0,空);
g_object_unref(应用程序);
}
int main(int argc,字符**argv)
{
while(getc(stdin)!='q'){
pthread_t d_线程;
pthread_create(&d_thread,NULL,(void*)gui_main,NULL);
}
返回0;
}

我的问题是:如何让两个线程同时运行,一个轮询服务器,另一个同时处理任意数量的Gtk窗口的打开和关闭,所有这些都是异步的?

我不确定Gtk是否可以运行多个GUI。尝试多进程设计?为什么你认为你需要线程?只需调用
g\u application\u hold()
,然后在激活时创建并关闭任意数量的窗口。我需要多线程,因为我有轮询线程,这在任何时候都不应该被中断。此外,我还计划实现另一个线程来处理套接字上的连接,这样我就可以编写一个与我的守护进程通信的客户端。使用Gio进行联网,为您处理异步线程。您的windows创建函数(
alarm_dialog
)绑定到激活信号,AFAIK会触发一次。如果将其绑定到多个事件,则会得到多个GtkWindows。顺便说一句,你把窗户漏水了。