0

我正在Oracle Outside In PDF ExportUbuntu Linux 上围绕库为 Node.js 编写 C++ 包装器。Node.js 有一个单线程事件循环,因此任何长时间运行的处理都是在工作线程上完成的。因此,我的包装器正在调用此工作线程内的所有 PDF 导出方法。我提到这一点是为了让您确定两件事:这是一个线程环境,并且所有 PDF 导出函数都在同一个工作线程上调用。此外,我没有使用任何重定向的 IO 或 PDF 导出处理的线程。我已经初始化了指定不使用线程的库。所以所有这些处理都应该发生在我调用函数的线程中。

导出单个 PDF 甚至可能快速连续导出两个或三个 PDF 时,一切似乎都很好。当我尝试导出的 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 上的函数是我的代码中的函数。这就是我调用所有 OIT lib 函数的函数。第 12 行及更高行的函数是与 Node.js 相关的线程函数,设置线程以运行我的代码的函数。第 10 行到第 1 行的函数都是 OIT 调用的函数。

在 PDF Export 的文档中,它说如果您要在线程环境中使用这个库,那么您每次都需要在工作线程中调用 init 和 deinit 函数。我在我的代码中这样做,你可以在这里看到:https ://github.com/ryancole/topdf/blob/master/src/topdf.cc#L29-L74

还有什么我需要设置的会导致这种情况吗?我只是明确地指定字体目录。这些库实际上是线程安全的吗?看起来不像。

4

1 回答 1

2

根据Oracle Outside In V 8.4.0 文档(第 4.2 章,第 50 页),您的调用DAInitEx是错误的,请检查第一个参数...

DAInitEx 应该只在每个应用程序启动时调用一次。在调用 DAInitEx 和 DADeInit 之间可以打开任意数量的文档以供访问。如果 DAInitEx 成功,无论任何其他 API 调用如何,都必须调用 DADeInit。

所有 Windows 平台以及 32 位版本的 Linux x86 和 Solaris SPARC 都支持多线程。线程函数初始化失败不会影响其他 API 调用。如果线程未初始化或失败,则调用存根函数而不是互斥函数。

于 2012-11-16T19:56:09.810 回答