Possible to run multiple main loops?

2020-07-09 08:34发布

问题:

I'm working with both libfuse and the glib event interface and I've run into an issue where I need to run multiple main loops concurrently (glib's g_main_loop_run and fuse_loop_mt).

I've already attempted to created a detached thread for glib's event loop under a secondary context, e.g.:

static void *
event_loop(void *arg)
{
  GMainLoop *event_loop;
  GMainContext *context;    

  context = g_main_context_new();
  g_main_context_push_thread_default(context);
  event_loop = g_main_loop_new(context, FALSE);
  g_main_loop_run(event_loop);

  return NULL;
}

...

pthread_t event_thread;
pthread_attr_t thread_attr;
pthread_attr_init(&thread_attr);
pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
event_thread = pthread_create(&event_thread, &thread_attr,
    event_loop, NULL);

However the glib event loop doesn't pick up on any of the fired events. Am I totally off-base here? What's the proper way to tackle multiple main loops?

回答1:

The GLib main loop supports custom event sources. I don't know much about FUSE, but you might be able to run FUSE's main loop within another thread, and integrate its events into the GLib loop.

A quick search suggests that you might be able to use a lower-level FUSE API to write your own main loop, which could presumably be integrated more readily into GLib's by simply skipping the "loop" part.

In general, though, multiple main loops are just bad news; that's why they're called main loops. :) The best way to handle them is to eliminate them by hooking events directly into whatever loop works best for you. Unfortunately, not all APIs provide the sufficient hooks to make that possible.



回答2:

Apart from setting up main loops in a separate thread or a process (from the little bit of experience I have had, separate process has worked better for me but then again thread might work well in your case), you can consider integrating fuse main loop in GLib's main loop (Unfortunately I have no prior experience with this). You can check this thread discussion about the same (in case you have not seen it already). As suggested at the end of the thread " Register the fuse device file descriptor (fuse_chan_fd()) with the glib event loop. Then call fuse_chan_recv() and fuse_session_process() when the event trigger". To track the fd you will need to use GIO(More info on Nokia developer page).
Hopefully this can provide some hints!