【问题标题】:Is Outside In's PDF Export library's function EXOpenExport thread-safe?Outside In PDF Export 库函数 EXOpenExport 是线程安全的吗?
【发布时间】:2012-11-16 19:39:15
【问题描述】:

我正在 Ubuntu Linux 上围绕 Oracle Outside In PDF Export 库为 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 导出的文档中,它说如果您要在线程环境中使用这个库,那么您需要每次在工作线程中调用 init 和 deinit 函数。我正在我的代码中执行此操作,您可以在此处查看:https://github.com/ryancole/topdf/blob/master/src/topdf.cc#L29-L74

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

【问题讨论】:

    标签: thread-safety oracle-outside-in


    【解决方案1】:

    根据Oracle Outside In V 8.4.0 documentation (Chapter 4.2, page 50),您对DAInitEx的调用是错误的,请检查第一个参数...

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

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

    【讨论】:

    • 嗯,我的意思是,如果我用DATHREAD_INIT_NOTHREADS 以外的东西调用DAInitEx,那么库将产生自己的线程来调用我的回调函数。这条线就是我在那里感到困惑的原因,我猜:The developer must actually code the threads after this function has been called. 另外,在那些文档中,它说的是关于运行线程的下面:On certain platforms, export products may be run in a multithreaded or multiprocessing application. The thing to remember when doing so is that each thread must go through all the steps listed in Chapter 1, "Introduction."
    • @Ryan 因为我这里没有这个库,所以我无法使用它:-(
    • Yahia,不管怎样,你似乎是对的!我将其更改为 PTHREAD 选项,这似乎有效。我只是误解了我猜想的文档,并且从未想过尝试该选项。谢谢你。 :)
    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2013-11-27
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多