我最近移植了一个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。这个库现在可能会引起干扰吗?
答案 0 :(得分:0)
问题是fork()创建了原始进程的精确副本,包括所有打开的文件句柄。 Qt似乎使用一些管道/套接字进行内部通信,因为这些是分叉进程中的相同的管道/套接字,它们与原始进程冲突。
使用exec()可能会更好运 - 据我所知,在分叉后无法安全地重新实例化QApplication。或者,如果在创建QApplication之前分叉,它应该可以工作。