woshidama323 / LearningGolang

1 stars 0 forks source link

钉钉消息 html转图片总结 #8

Open woshidama323 opened 2 years ago

woshidama323 commented 2 years ago

在golang 自行调度的场景下,wkhtmltoimage (wkhtmltopdf)这个工具遇到的一些问题

  1. 因为依赖qt 而qt 需要在主线程中创建application

    WARNING: QApplication was not created in main() thread

    这样造成的后果是 因为qt没有初始化好,后面转换出现了乱码

  2. cgo调用c代码的时候,如果go的调度器切换了线程,那么cgo有可能会失败 cgo Interacting with C Library that uses Thread Local Storage

//https://github.com/bratsche/glib/blob/master/glib/gmain.c
/**
 * g_main_context_pop_thread_default:
 * @context: a #GMainContext object, or %NULL
 *
 * Pops @context off the thread-default context stack (verifying that
 * it was on the top of the stack).
 *
 * Since: 2.22
 **/
void
g_main_context_pop_thread_default (GMainContext *context)
{
  GQueue *stack;

  if (context == g_main_context_default ())
    context = NULL;

  stack = g_static_private_get (&thread_context_stack);

  g_return_if_fail (stack != NULL);
  g_return_if_fail (g_queue_peek_head (stack) == context);

  g_queue_pop_head (stack);

  g_main_context_release (context);
  if (context)
    g_main_context_unref (context);
}
(process:14437): GLib-CRITICAL **: 03:30:03.635: g_main_context_pop_thread_default: assertion 'stack != NULL' failed
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x7fb271104041]

runtime stack:
runtime.throw(0x117aaed, 0x2a)
    /usr/local/go/src/runtime/panic.go:1116 +0x72
runtime.sigpanic()
    /usr/local/go/src/runtime/signal_unix.go:726 +0x4ac

goroutine 23316 [syscall]:
runtime.cgocall(0xef1610, 0xc0008c99e8, 0xc0008c99f0)
    /usr/local/go/src/runtime/cgocall.go:133 +0x5b fp=0xc0008c99b8 sp=0xc0008c9980 pc=0x4058bb
github.com/shezadkhan137/go-wkhtmltoimage._Cfunc_wkhtmltoimage_deinit(0x0)
    _cgo_gotypes.go:143 +0x49 fp=0xc0008c99e8 sp=0xc0008c99b8 pc=0xd779a9
github.com/shezadkhan137/go-wkhtmltoimage.Destroy()

最终的解决办法是用

runtime.LockOSThread()
runtime.UnlockOSThread()
通过不让调度器切换线程来避免这样的问题,这样的操作当然是有代价的 性能会下降