一个非常简单的屏幕保护程序可以工作几个小时,然后突然屏幕变黑,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)
答案 0 :(得分:0)
我无法找到根本原因,但是通过删除处理事件的第二个线程来解决问题
相反,我在主循环中添加了一个非阻塞函数XCheckTypedEvent()
。
所以原来的问题在某种程度上与多线程本身有关:即使第二个线程空闲等待事件(并且没有事件!)阻塞XNextEvent()
,主循环在几个小时后失败。