2

在使用 Glibs GMainLoop 时,我遇到了一些文件描述符挂起的问题。我已将其缩小为一个具有一个事件的简单循环。

我在运行程序时正在监视文件描述符,并注意到有几个文件描述符永远不会关闭。

请看这个例子:

#include <stdio.h>
#include <glib.h>
#include <gio/gio.h>
#include <string.h>
#include <unistd.h>

static gboolean
timeout(gpointer user_data)
{
    printf("## %s\n", __FUNCTION__);
    g_main_loop_quit((GMainLoop*)user_data);
}

int
main(int argc, char **argv)
{
    g_type_init();

    printf("Check lsof now...\n");
    sleep(10);
    printf("--- time's up ---\n");

    GMainContext *ctx = g_main_context_new();
    GMainLoop *loop = g_main_loop_new(ctx, FALSE);
    g_main_context_push_thread_default(ctx);

    GSource *timer = g_timeout_source_new(2000);
    g_source_set_callback(timer, timeout, loop, NULL);
    g_source_attach(timer, ctx);

    g_main_loop_run(loop);

    g_main_context_pop_thread_default(ctx);
    g_source_unref(timer);
    g_main_loop_unref(loop);
    g_main_context_unref(ctx);

    printf("Check lsof now...\n");
    sleep(10);
    printf("--- time's up ---\n");
    return 0;
}

在代码中标记的地方,我正在检查程序打开的文件描述符的数量。在第一个检查点有 3 个(忽略库等):

a.out   16333 hansm    0u   CHR 136,43      0t0      46 /dev/pts/43
a.out   16333 hansm    1u   CHR 136,43      0t0      46 /dev/pts/43
a.out   16333 hansm    2u   CHR 136,43      0t0      46 /dev/pts/43

在第二个检查点有五个:

a.out   16873 hansm    0u   CHR 136,43      0t0        46 /dev/pts/43
a.out   16873 hansm    1u   CHR 136,43      0t0        46 /dev/pts/43
a.out   16873 hansm    2u   CHR 136,43      0t0        46 /dev/pts/43
a.out   16873 hansm    5r  FIFO    0,8      0t0 149228995 pipe
a.out   16873 hansm    6w  FIFO    0,8      0t0 149228995 pipe

为什么这些管道没有关闭?

Valgrind 没有报告错误(除了一些“可能丢失的记忆”)。

fd(上面示例中的 5 和 6)在执行时打开

GMainContext *ctx = g_main_context_new();

而且显然从未关闭。我究竟做错了什么?

4

0 回答 0