关于等待在串行 link 上读取的数据的通知

notification on data waiting to be read on serial link

我尝试向我的 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 主循环迭代期间停止调用回调...

尝试在 g_io_add_watch 之后立即添加 g_io_channel_unref(channel)。然后在你的回调中添加

if(G_IO_STATUS_EOF == status)
 return FALSE;

g_io_channel_*_new() returns a GIOChannel object with a reference count of one. g_io_add_watch() adds a further reference count - if you decrement it by 1, the callback will be disconnected and the relevant GSource object removed when the callback returns FALSE, which it should do when it detects end-of-file, or if you call g_source_remove() on the return value of g_io_add_watch()

在 Linux 上,GLib g_io_add_watch 方法将您的文件描述符添加到 poll()。轮询 /dev 文件与套接字描述符或普通文件不同。检查驱动程序中的 struct fops 结构,了解您的驱动程序是否支持轮询操作。通常他们确实支持,除非您使用一些自定义驱动程序。还要将您的代码与任何其他 /dev 文件进行交叉检查。

查看回调中g_io_channel_read_line返回的状态是否为G_IO_STATUS_AGAIN,即资源暂时不可用;因此,您的文件描述符上发生了一个事件,但没有可从驱动程序缓冲区读取的即时数据。