我有多线程应用程序,每个线程创建自己的表面,渲染内容,保存和销毁所有。
然而,过了一段时间(如。20张图片被保存下来),这个应用程序在_cairo_atomic_init_once_enter中运行,来自cairo-atomic-private.h。
下面是的堆栈跟踪:
[Inline Frame] app.exe!_cairo_atomic_init_once_enter(unsigned int *) Line 409 C
app.exe!_cairo_image_spans_compositor_get() Line 3135 C
[Inline Frame] app.exe!_cairo_image_surface_init(_cairo_image_surface *) Line 176 C
app.exe!_cairo_image_surface_create_for_pixman_image(pixman_image * pixman_image=0x0000023c1d1f31f0, pixman_format_code_t pixman_format=PIXMAN_a8r8g8b8) Line 197 C
app.exe!_cairo_image_surface_create_with_pixman_format(unsigned char * data=0x0000000000000000, pixman_format_code_t pixman_format=PIXMAN_a8r8g8b8, int width, int height, int stride=-1) Line 355 C
app.exe!cairo_image_surface_create(_cairo_format format, int width, int height) Line 403 C我打电话说:
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, int(w), int(h));我的并行循环通过以下方式完成:
std::vector<int> xSeq(countX);
std::iota(std::begin(xSeq), std::end(xSeq), 0); // Fill with 0, 1, ..., countX.
std::for_each(std::execution::par, std::begin(xSeq), std::end(xSeq), [&](auto x)
{
//create cairo surface, write to it, store it and release it
}如果我运行串行版本,一切都正常工作。
编辑:存储表面到图像,我不使用内部PNG保护程序。我有自己的执行,这是基于:
cairo_surface_flush(surface);
data = cairo_image_surface_get_data(surface);data包含来自cairo的原始数据,我手动处理它们,并将它们存储在自己的压缩系统中。
在某些情况下,我还使用相同的系统将数据“注入”到cairo面。我获得data指针,手动重写一些像素,并调用cairo_surface_mark_dirty(surface)通知Cairo更改。
发布于 2019-09-27 05:38:22
这并不是真正的答案,但你所看到的行为应该是不可能的。
_cairo_image_traps_compositor_get有一个cairo_atomic_once_t变量,用于保护某些初始化。因为它是静态的,所以我们可以确保没有其他代码接触到这个变量。
_cairo_atomic_init_once_enter检查once是否已经初始化,然后只返回0/ false。因为你说你已经有20个成功的电话,初始化必须已经完成。否则,其他20个电话就不应该起作用。
根据上面的..。这是不可能的,对吧?除非某些东西覆盖了一些它不应该触及的内存,并且once的值被破坏了,或者类似的东西。或者,这是由于我不明白的原因而产生的某种错误编译。你是自己编译开罗的,还是从哪里得到的?
https://stackoverflow.com/questions/58120390
复制相似问题