0

私はUbuntuLinuxで、Oracle Outside In PDF Exportライブラリの周りにNode.js用のC++ラッパーを書いています。Node.jsにはシングルスレッドのイベントループがあるため、長時間実行される処理はワーカースレッドで実行されます。したがって、私のラッパーは、このワーカースレッド内のすべてのPDFエクスポートメソッドを呼び出しています。これについては、2つのことを確認できるように説明します。これはスレッド化された環境であり、すべてのPDFエクスポート関数が同じワーカースレッドで呼び出されています。また、リダイレクトされたIOまたはPDFエクスポートで処理されるスレッドを使用していません。スレッドを使用しないように指定してライブラリを初期化しました。したがって、この処理はすべて、関数を呼び出すスレッド内で行われる必要があります。

1つのPDFをエクスポートする場合、または2つまたは3つをすばやく連続してエクスポートする場合でも、すべてがうまくいくようです。エクスポートしようとするPDFの数を5以上に増やすと、OITライブラリ内からSIGSEGVセグメンテーション違反が発生します。バックトレースは以下のとおりです。

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff4fd0700 (LWP 1577)]
0x00007fffeef1da26 in HandlePoolCreateHandle () from /usr/local/lib/pdfexport/libwv_core.so
(gdb) bt
#0  0x00007fffeef1da26 in HandlePoolCreateHandle () from /usr/local/lib/pdfexport/libwv_core.so
#1  0x00007fffeef1925d in Win32VCreateHandle () from /usr/local/lib/pdfexport/libwv_core.so
#2  0x00007fffed49046b in WrapBrush(void*, GdiBrush*) () from /usr/local/lib/pdfexport/libos_pdf.so
#3  0x00007fffed46e8c8 in ?? () from /usr/local/lib/pdfexport/libos_pdf.so
#4  0x00007fffed46df63 in GNGetOutputSolutionInfoAt () from /usr/local/lib/pdfexport/libos_pdf.so
#5  0x00007fffeef1e32a in ?? () from /usr/local/lib/pdfexport/libwv_core.so
#6  0x00007fffeef1e214 in ?? () from /usr/local/lib/pdfexport/libwv_core.so
#7  0x00007fffeef18ed3 in Win32VLoadOS () from /usr/local/lib/pdfexport/libwv_core.so
#8  0x00007fffeddffb24 in VwExportOpen () from /usr/local/lib/pdfexport/libex_pagelayout.so
#9  0x00007ffff4062c4d in FAOpenExport () from /usr/local/lib/pdfexport/libsc_fa.so
#10 0x00007ffff7e53270 in EXOpenExport () from /usr/local/lib/pdfexport/libsc_ex.so
#11 0x00007ffff43c0a4d in topdf_convert(uv_work_s*) ()
   from /home/ryan/repos/pdf-service/node_modules/topdf/build/Release/topdf.node
#12 0x00000000006e2ec7 in worker (arg=<optimized out>) at ../deps/uv/src/unix/threadpool.c:65
#13 0x00007ffff6fa6e9a in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#14 0x00007ffff6cd3cbd in clone () from /lib/x86_64-linux-gnu/libc.so.6
#15 0x0000000000000000 in ?? ()

バックトレースについて少し説明します。#11の関数は、私のコード内の関数です。これが、すべてのOITlib関数を呼び出す関数です。行#12以降の関数は、Node.js関連のスレッド関数であり、コードの関数を実行するようにスレッドを設定します。行#10から#1までの関数は、すべてOITと呼ばれる関数です。

PDFエクスポートのドキュメントには、スレッド環境内でこのライブラリを使用する場合は、ワーカースレッド内で毎回init関数とdeinit関数を呼び出す必要があると記載されています。私は自分のコードでこれを行っています。これは次の場所で確認できます:https ://github.com/ryancole/topdf/blob/master/src/topdf.cc#L29-L74

これを引き起こすような設定が必要なものは他にありますか?フォントディレクトリを明示的に指定しているだけです。これらのライブラリは実際にスレッドセーフですか?彼らがそうであるようには見えません。

4

1 に答える 1

2

Oracle Outside V 8.4.0のドキュメント(第4.2章、50ページ)によると、呼び出しDAInitExが間違っている場合は、最初のパラメータを確認してください...

DAInitExは、アプリケーションの起動時に、アプリケーションごとに1回だけ呼び出す必要があります。DAInitExとDADeInitの呼び出し間でアクセスするために、任意の数のドキュメントを開くことができます。DAInitExが成功した場合、他のAPI呼び出しに関係なく、DADeInitを呼び出す必要があります。

複数のスレッドは、すべてのWindowsプラットフォームと、32ビットバージョンのLinuxx86およびSolarisSPARCでサポートされています。スレッド関数の初期化に失敗しても、他のAPI呼び出しが損なわれることはありません。スレッド化が初期化されていないか失敗した場合、ミューテックス関数の代わりにスタブ関数が呼び出されます。

于 2012-11-16T19:56:09.810 に答える