我尝试在g_main_loop上添加一个新的源代码,它是一个外围串行线上的文件描述符。
我试试这段代码:
GError* error;
GIOChannel* channel;
channel=g_io_channel_unix_new(fd_serial_line_dev);
g_io_add_watch(channel, G_IO_IN, cb_1, NULL);
g_io_channel_set_close_on_unref(channel, TRUE);
g_io_channel_set_encoding(channel, NULL, &error);
g_io_channel_set_buffered(channel, FALSE);
回调是:
gboolean cb_1 (GIOChannel *source, GIOCondition condition, gpointer data)
{
gchar** line=NULL;
GIOStatus status;
GError* error;
printf("cb\n");
status=g_io_channel_read_line(source, line, NULL, NULL, &error);
if(G_IO_STATUS_NORMAL == status)
{
printf("callback : data : %s\n", *line);
g_free(*line);
//g_io_channel_seek_position(source, 0, G_SEEK_CUR, NULL);
}
return TRUE;
}
当我在串行线上发送数据时,我获得了一个每次调用cb_1的无限循环。
我不知道我的错误在哪里,我预计在下一个g主循环迭代期间,串行线路的文件描述符内的读取将足以停止对回调的调用...
答案 0 :(得分:1)
尝试在g_io_add_watch之后添加g_io_channel_unref(channel)
immediatley。然后在你的回调中添加
if(G_IO_STATUS_EOF == status)
return FALSE;
g_io_channel _ * _ new()返回GIOChannel 引用计数为1的对象。 g_io_add_watch()进一步增加了 引用计数 - 如果将其减1,则回调将为 断开连接并在回调时删除相关的GSource对象 返回FALSE,它在检测到文件结束时应该执行,或者是 你在g_io_add_watch()
的返回值上调用g_source_remove()
答案 1 :(得分:1)
在Linux上,GLib g_io_add_watch方法将您的文件描述符添加到poll()。 / dev文件上的轮询与套接字描述符或普通文件不同。检查驱动程序中的struct fops结构,以了解驱动程序是否支持轮询操作。除非您使用某些自定义驱动程序,否则通常它们会支持还要与任何其他/ dev文件交叉检查您的代码。
检查回调中g_io_channel_read_line返回的状态是否为G_IO_STATUS_AGAIN,这意味着资源暂时不可用;因此,您的文件描述符上发生了一个事件,但没有可立即从驱动程序缓冲区中读取的数据。