簡體   English   中英

在 GLIB 主循環中添加 fds

[英]Add fds in the GLIB mainloop

我需要將文件描述符附加到 GLIB 主循環。 我的問題是文件描述符列表在執行過程中不是固定的。

根據 GLIB 文檔,我可以:

  • 創建每個FD一個GIOChannel使用g_io_channel_unix_new並將其附加到與g_io_add_watch上下文
  • 使用由g_io_create_watch創建的Gsource並設置回調g_source_set_callback

我的問題是:是否可以動態修改源或上下文。 我該怎么做? 我發現 GSourceFuncs 能力,但這不適合我的問題。

謝謝你的幫助。

g_io_add_watch返回一個事件源 ID,您可以稍后使用g_source_remove再次動態刪除監視。 每個 FD 使用一個事件源,而不是修改現有手表,刪除舊手表並創建適當的新手表。

我深入研究了 GLIB,現在:

  • 我創建了一個帶有回調函數的源(准備、檢查、調度、完成)
  • 在准備回調中,使用 g_source_remove_unix_fd() 刪除 FD,然后使用 g_source_add_unix_fd() 添加到當前源。
  • 我返回 FALSE 來設置超時(我的例子是 1s)

我的問題是,如果沒有 FD,准備回調按預期每 1 次調用一次。 添加 FD 時,會在不超時的情況下調用准備回調。 投票直接退出。

我查看了 GLIB 源代碼,但不明白為什么?

幫助請問候

amenophiks 的回答是最好的。

如果您希望您的代碼使用較舊的 glib,您可以使用:

  • g_source_add_poll()
  • g_source_remove_poll()

你讀過主事件循環文檔嗎? 描述部分很好地解釋了事情是如何工作的。

你看過自定義 GSource教程嗎? 這允許您擴展 GSource 對象以包含您自己的狀態。 您還可以編寫自己的准備、調度、查詢和檢查功能。

每當我真的想看看應該如何使用 GLib、GTK 等來完成某些事情時,我首先查看的是位於其 git 存儲庫中的測試代碼。 請務必為您的目標版本簽出正確的標簽。

例如我目前的目標是 2.48.2

這里有兩個很好的例子https://gitlab.gnome.org/GNOME/glib/blob/2.48.2/tests/mainloop-test.c https://gitlab.gnome.org/GNOME/glib/blob/2.48 .2/glib/tests/mainloop.c

另一個不錯的功能是它是一個 git 存儲庫,因此您可以非常輕松地搜索它。

似乎,我發現了一個小鈎子。 嘗試這個:

struct source {
    GSource gsrc;
    GPollFD *gpfd;
};

struct data {
    /* A something data. */
};

static gboolean gsrc_dispatch(GSource *gsrc, GSourceFunc cb, gpointer data);
static struct data * data_alloc(void);

static GSourceFuncs gsf = {
    .prepare = NULL,
    .check = NULL,
    .dispatch = gsrc_dispatch,
    .finalize = NULL
};

int main(void)
{
    struct source *src;
    int fd;
    struct data *data = data_alloc();

    /* Something other. */

    /* For example, we are want to capture video from a camera. */
    fd = open("/dev/video0", O_RDWR);
    if (fd < 0) {
        perror("open()");

        return -1;
    }

    src = (struct source *) g_source_new(&gsf, sizeof(struct source));
    src->gpfd = g_source_add_unix_fd((GSource *) src, fd, G_IO_IN);

    g_source_set_callback((GSource *) src, NULL, data, NULL);
    g_source_attach((GSource *) src, NULL);

    /* Something other and free. */

    return 0;
}

static gboolean
gsrc_dispatch(GSource *gsrc, GSourceFunc cb, gpointer data)
{
    struct source *src = (struct source *) gsrc;
    struct data *d = data;

    if (src->gpfd != NULL) {
        if (src->gpfd->revents & G_IO_IN) {
            /* Capture a frame. */
        }
    }

    g_main_context_iteration(NULL, TRUE);

    return G_SOURCE_CONTINUE;
}

static struct data *
data_alloc(void)
{
    /* Allocate a data. */
}

是的,您可以使用雙gpfd指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM