2012-04-06 13 views
0

最近Qtアプリを移植して、posixの代わりにQTcpSocketsを使用しました。私が使用しているレンダラーは、まだ実行されていない場合、フォークによってビューアプリケーションを起動するコードを持っています。私の新しいリファクタリングされたアプリでは、レンダラーを実行する前にアプリが起動されていれば正常に動作するようです。しかし、既に実行しているビューアプリケーションを使わずにレンダラーを起動すると、フォークコードが呼び出され、通常はレンダリングの途中でプログラムがクラッシュします。フォーク()メソッドを使用する場合、この例外がスローされただけますので、それはリファクタリングで何かあればプログラムからforkしたときに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 

、私は思ったんだけど?私はまた、レンダラ(ビューアアプリケーションを起動する)を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を作成するとうまくいくはずです。

関連する問題