一尘不染

使用JAVA中的PID验证进程是否正在运行

linux

我目前正在JAVA中构建一个应用程序,其中只能执行一次。因此,我当前正在使用一个锁定文件,在其中写入当前执行的PID。

因此,只要此应用程序启动,它将打开文件(如果存在)并尝试检测写入文件的PID是否正在实际运行。

这样可以防止我的应用在解锁文件之前崩溃的问题。

我需要它在Windows(XP,7或8)和linux(所有用户都在基于debian的发行版)上工作。

这是一些代码,可以让您更好地了解我想做什么:

//get the PID from the file
int pidValue = new FileReader(file).read();

//get the OS type
String os = System.getProperty("os.name").toLowerCase();

//Check PID depending of OS type
if( os.contains("nux") || os.contains("nix") ){
/*
 * Check PID on Linux/Unix
*/
} else if ( os.contains("win") ) {
/*
 * Check PID on Windows
 */
}

我试图找到有关该主题的文档,但还没有找到有用的东西。

非常感谢你。


阅读 496

收藏
2020-06-07

共1个答案

一尘不染

在posix系统上,查询pid是否正在运行的典型方法是向其发送空信号,例如kill(pid, 0)。如果调用成功,则存在该过程;如果返回ESRCH,则不返回。这自然会遇到不可避免的种族条件,这实际上比理论上要少得多。不太统一的方法是读取/
proc文件系统(如果操作系统具有该文件系统),这会花费更多的精力,相当于同一件事,并且仍然受相同的竞争条件的影响。

请注意,pid锁定文件技术可以分为两层。也就是说,正在运行的进程将创建文件,将其锁定并写入其pid。它在运行期间保持锁定,因此这几乎不需要上面查询进程是否正在运行的原因,因为如果进程崩溃,即使文件仍然存在,文件锁也会自动释放。逻辑如下:

if file exists
   if can get lock
       prev instance died unnaturally
       continue with this new process
   else
       instance already running
else
   good to go, continue with new process

此技术还具有比赛条件。

我不记得有足够的Java来说它是否具有包装器kill或文件锁定系统调用(如)flocklockf并且是否fcntl需要实施此方案。

2020-06-07