我的主要问题是:是否可以通过守护进程(upstart 脚本)运行 OPENGL 程序?该程序在屏幕上显示一个窗口。
更多详细信息:我有一个 opengl 程序(使用 openframeworks、C++ 完成),我想用守护进程运行它。
我像这样在终端中手动启动我的程序:
planeviz@planeviz:~/src/of/apps/myApps/planeEtoiles/bin$ ./planeEtoiles
现在我创建了一个 upstart 脚本(/etc/init/myapp.conf),它应该在计算机启动时启动该程序,并确保在崩溃时重新启动它。
# job file
description "myapp"
author "eva"
# When to start the service
start on startup
start on runlevel [2345]
# When to stop the service
stop on runlevel [016]
# Automatically restart process if crashed
respawn
# Start the process
script
sudo /home/planeviz/src/of/apps/myApps/planeEtoiles/bin/planeEtoiles
end script
然后我尝试通过以下方式启动守护进程
sudo service myapp start
我的应用程序没有打开。dmesg 告诉我:
planeviz@planeviz:/etc/init$ dmesg | grep "init:"
[ 5282.003496] init: myapp main process (8008) terminated with status 139
终止状态 139 似乎暗示存在分段错误。查看 upstart 日志中程序的输出,我发现最后一个错误与 opengl 窗口的创建有关。
planeviz@planeviz:/etc/init$ sudo tail /var/log/upstart/planeetoiles.log
....
[ error ] ofAppGLFWWindow: couldn't init GLFW
这让我怀疑是否有可能用 upstart 运行 OPENGL 程序,或者它是否只能与后台进程一起工作?
答案1
Upstart 是为系统服务而设计的。虽然你可以(至少在最新版本中)使用它来监视用户会话期间运行的命令,但它很笨拙。
使用 Upstart,如果您想运行显示 GUI 窗口的服务,则该服务只能在您登录时运行。您不是根据运行级别来启动和停止,而是需要根据 GUI 登录和注销事件来启动和停止。
start on desktop-session-start
stop on desktop-shutdown
您还需要该服务能够到达您的显示器。GUI 应用程序使用DISPLAY
环境变量来确定显示位置。在正常情况下,您的 GUI 会话将是名为 的显示器:0
。
env DISPLAY=:0
应用程序还需要获得访问显示的权限。此权限采用“cookie”(密码)的形式,它会在您的 GUI 会话启动时自动生成并存储在.Xauthority
主目录中的文件中(或XAUTHORITY
环境变量指示的另一个文件,具体取决于您的显示管理器)。如果您的显示管理器使用~/.Xauthority
并且您以您的用户身份运行该服务(您无论如何都应该这样做),则无需设置XAUTHORITY
。有关更多详细信息,请参阅我可以以 root 身份启动其他用户桌面上的图形程序吗?和在远程 X 显示器上打开一个窗口(为什么“无法打开显示”)?
setuid evsc
除了Upstart,还可以使用只做监管而不做系统服务管理的监管工具。确保进程始终运行列出了几种可能性。让我们使用supervise
从守护进程工具。在某处创建一个目录,例如~/.planeEtoiles
。在此目录中,创建一个名为的可执行文件run
,它是您想要继续运行的应用程序:
mkdir ~/.planeEtoiles
ln -s /home/planeviz/src/of/apps/myApps/planeEtoiles/bin/planeEtoiles ~/.planeEtoiles/run
将命令添加supervise ~/.planeEtoiles
到登录时自动启动的应用程序。要停止服务,请使用svc
命令:
svc -t -x ~/.planeEtoiles
最后一个难题是svc
注销时运行该命令。这个功能似乎缺失了,或者记录得非常少。如果你使用 GDM,有一个解决方法,即从/etc/gdm/PostSession/Default
,但该文件以 root 身份运行命令,这不是一个好的解决方案,并且不适用于 Lightdm。监控用户注销时执行脚本(非 root 用户)和如果我没有管理员权限,如何在 GNOME 注销期间运行脚本?寻找解决方案。