应用程序为什么/如何保留另一个进程创建的互斥体引用?
我有一个有点不寻常的流程结构:
- Launch4J 启动我的 Java 应用程序。它创建一个互斥体来为 Java 应用程序提供单实例功能。
- Java 应用程序启动一个 VB6 应用程序,该应用程序可以有多个实例。
- 当Java应用程序终止时,VB6应用程序仍在运行。 (期望的行为)
问题是:Launch4J 创建的互斥锁仅在 VB6 应用程序终止后释放。因此,不可能再次启动 Java 应用程序。
为什么会出现这种情况呢?我没有明确地打开互斥锁...
我首先怀疑这是因为 Java 使用 CreateProcess
和 bInheritHandles == true
造成的,但是当我开始时问题并没有发生例如 notepad.exe
。
编辑:我仍然有这个问题。任何指点表示赞赏!
I have this somewhat unusual process structure:
- Launch4J starts my Java application. It creates a mutex to provide single-instance functionality for the Java application.
- The Java application starts a VB6 application, which can have multiple instances.
- When the Java application terminates, the VB6 application is still running. (Desired behaviour)
The problem is: The mutex created by Launch4J is only released after the VB6 application terminates. Because of that it's impossible to start the Java application again.
Why would this happen? I'm not opening the mutex explictly...
I first suspected it is because of Java using CreateProcess
with bInheritHandles == true
, but the problem does not occour when I start notepad.exe
for example.
EDIT: I still have this problem. Any pointers are appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Launch4J 在终止之前是否释放互斥体并关闭其句柄?抱歉,我不知道 Java 如何包装操作系统互斥体函数,但您应该确保在线程结束之前显式释放互斥体并关闭其句柄。
Does Launch4J release the mutex and close its handle before terminating? I'm sorry, but I don't know how Java wraps the OS Mutex functions, but you should ensure you explicitly release the mutex and close its handle before your thread ends.
我遇到了同样的问题,并意识到 Launch4J 在启动时创建一个可继承互斥体,并且当从 JVM 中启动进程时,该互斥体将由新进程继承。
JVM 关闭后,互斥锁仍由新进程持有。
我发现避免继承互斥锁的最简单解决方案是使用中间程序,该程序将进程作为分离进程启动,而不继承父句柄。
该程序的 C++ 示例可以在这里找到 https://stackoverflow.com/a/1582197/6894604
只需编译使用 c++ 编译器运行程序(“ex: rujob.exe”)并更改命令以使用启动器而不是直接调用进程,例如:
这样您的 VB 程序将不会继承 java 应用程序互斥体,也不会阻止您的java应用程序再次启动。
I faced the same kind of issue and realized that Launch4J creates an inheritable mutex on startup and when launching a process from withing the JVM, this mutex is then inherited by the new process.
After JVM shutdown the mutex is still held by the new process.
The simplest solution I found to avoid the mutex to be inherited is to use an intermediate program that launches a process as a detached process without inheriting the parent handles.
A working c++ example of this program can be found here https://stackoverflow.com/a/1582197/6894604
Just compile the program (“ex: rujob.exe”) using a c++ compiler and change your command to use the launcher instead of directly calling the process, for example :
This way your VB program will not inherit the java application mutex and will not prevent your java app to start again.
为什么不使用 VB 而不是 java 提供单实例功能? IMO 使用 Launch4j 为 VB 应用程序提供单个实例是错误的。还有其他方法,请检查:
https://www.vbforums.com/showthread.php?342810-Classic-VB-How-can-I-allow-only-一次运行我的应用程序的一个实例
Why don't you provide single instance functionality using VB instead of java? IMO it is wrong to provide single instance for the VB app using Launch4j. There are other ways, check this:
https://www.vbforums.com/showthread.php?342810-Classic-VB-How-can-I-allow-only-one-instance-of-my-application-to-run-at-a-time