Xlib:简单程序占用90%的CPU

时间:2017-10-03 17:11:57

标签: cpu-usage xlib xorg

一个非常简单的屏幕保护程序可以工作几个小时,然后突然屏幕变黑,CPU跳到90%。内存消耗仅增加4kB并保持不变。

while (1)
{   
    XClearWindow(dpy, win);
    // draw a logo 259x64 pixels
    XPutImage(dpy, win, gc, img, 0, 0, random()%(WIDTH-LOGO_WIDTH), random()%(HEIGHT-LOGO_HEIGHT), LOGO_WIDTH, LOGO_HEIGHT);
    XFlush(dpy);
    usleep (DELAY_US);    // 1 sec delay
}

top的输出:

   PID USER     PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                 
  2717 aspen    20   0   12580   1868   1504 R 91.5  0.4 838:05.68 screensaver

编辑: 另一个线程处理事件。当程序开始消耗大量CPU时,没有打印出任何内容,即没有事件。

static events()
{
    XNextEvent (dpy, &event);
    switch (event.type)
    {   
        case ButtonPress:
            XCloseDisplay (dpy);
            printf ("Let's go work!\n");
            exit (1);
        default:
            printf ("Event: %d\n", event.type);
    }
}

gdb输出(使用gcore转储的核心):

(gdb) thread 1
[Switching to thread 1 (Thread 0xb6f21000 (LWP 2654))]
#0  0xb6e22ffa in _XReply () from /usr/lib/arm-linux-gnueabihf/libX11.so.6
(gdb) bt
#0  0xb6e22ffa in _XReply () from /usr/lib/arm-linux-gnueabihf/libX11.so.6
#1  0xb6e24b2c in ?? () from /usr/lib/arm-linux-gnueabihf/libX11.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) thread 2
[Switching to thread 2 (Thread 0xb6c54470 (LWP 2655))]
#0  0xb6d60580 in poll () at ../sysdeps/unix/syscall-template.S:84
84      in ../sysdeps/unix/syscall-template.S
(gdb) bt
#0  0xb6d60580 in poll () at ../sysdeps/unix/syscall-template.S:84
#1  0xb6cb3ec4 in ?? () from /usr/lib/arm-linux-gnueabihf/libxcb.so.1
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

感谢您提供有关排查问题的建议/指示。

xorg-server 1.19.2(Debian 9.1)

1 个答案:

答案 0 :(得分:0)

我无法找到根本原因,但是通过删除处理事件的第二个线程来解决问题 相反,我在主循环中添加了一个非阻塞函数XCheckTypedEvent()。 所以原来的问题在某种程度上与多线程本身有关:即使第二个线程空闲等待事件(并且没有事件!)阻塞XNextEvent(),主循环在几个小时后失败。