2012-04-06 46 views
0

我最近移植了一個Qt應用程序來直接使用QTcpSockets而不是posix。我正在使用的渲染器具有代碼,如果它尚未運行,則通過分叉來啓動視圖應用程序。使用我最近重構的應用程序,如果在運行渲染器之前啓動應用程序,它似乎可以正常工作。但是,如果我在未運行視圖應用程序的情況下啓動渲染器,則會調用分叉代碼,程序通常會在渲染過程中中途崩潰。從程序分叉時提升dataflow_exception

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應用程序內部運行渲染器(啓動查看器應用)時纔會發生這種情況。當視圖應用直接從渲染器分離出來時,我看不到這個問題。我不確定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

問題是fork()會創建原始進程的精確副本,包括所有打開的文件句柄。 Qt似乎使用一些管道/套接字進行內部通信,因爲這些是在分叉進程中的相同的管道/套接字,它們與原始進程衝突。

使用exec()代替你可能會有更好的運氣 - 據我所知,在分叉之後沒有辦法安全地重新實例化QApplication。或者,如果您在創建QApplication之前在之前分叉,它應該可以工作。