使用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();
显然从未关闭过。我做错了什么?