从程序分叉时提升dataflow_exception

时间:2012-04-06 13:34:55

标签: c++ qt boost

我最近移植了一个Qt应用程序,直接使用QTcpSockets代替posix。我正在使用的渲染器有代码通过分叉启动视图应用程序,如果它还没有运行。使用我新重构的应用程序,如果在运行我的渲染器之前启动应用程序,它似乎工作正常。但是,如果我在没有运行视图应用程序的情况下启动渲染器,它将调用fork代码,程序通常会在渲染中途崩溃。

Qt has caught an exception thrown from an event handler. Throwing
exceptions from an event handler is not supported in Qt. You must
reimplement QApplication::notify() and catch all exceptions there.

terminate called after throwing an instance of '
boost::archive::iterators::dataflow_exception'
  what():  attempt to decode a value not in base64 char set

因为只有在使用fork()方法时抛出此异常,我才想知道它是否在重构中?我也相信只有在Qt app从内部运行渲染器(启动查看器应用程序)时才会发生这种情况。当视图应用程序直接从渲染器分叉时,我没有看到此问题。我不确定fork()可能会做什么导致此异常。

int pid = fork();
if (pid != -1)
{
    if (!pid)
    {
        // Child process executes the following after forking.
    char arg1[] = "piqsl";
    char arg2[] = "-i";
    char arg3[] = "127.0.0.1";
    char* argv[4] = {arg1, arg2, arg3, NULL};
    // TODO: need to pass verbosity level for logginng
    signal(SIGHUP, SIG_IGN);
    nice(2);
    execvp("piqsl",argv);
...

重构的查看器应用程序的唯一区别是它使用QTcpSockets(和QTcpServer),现在链接到libQNetwork。这个库现在可能会引起干扰吗?

1 个答案:

答案 0 :(得分:0)

问题是fork()创建了原始进程的精确副本,包括所有打开的文件句柄。 Qt似乎使用一些管道/套接字进行内部通信,因为这些是分叉进程中的相同的管道/套接字,它们与原始进程冲突。

使用exec()可能会更好运 - 据我所知,在分叉后无法安全地重新实例化QApplication。或者,如果在创建QApplication之前分叉,它应该可以工作。