Open woshidama323 opened 2 years ago
在golang 自行调度的场景下,wkhtmltoimage (wkhtmltopdf)这个工具遇到的一些问题
因为依赖qt 而qt 需要在主线程中创建application
WARNING: QApplication was not created in main() thread
这样造成的后果是 因为qt没有初始化好,后面转换出现了乱码
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() 通过不让调度器切换线程来避免这样的问题,这样的操作当然是有代价的 性能会下降
在golang 自行调度的场景下,wkhtmltoimage (wkhtmltopdf)这个工具遇到的一些问题
因为依赖qt 而qt 需要在主线程中创建application
这样造成的后果是 因为qt没有初始化好,后面转换出现了乱码
cgo调用c代码的时候,如果go的调度器切换了线程,那么cgo有可能会失败 cgo Interacting with C Library that uses Thread Local Storage
最终的解决办法是用