如何同时处理多个并发实例?

时间:2012-07-24 14:04:43

标签: c++ linux qt ubuntu multiple-instances

这就是问题所在: 我不喜欢我的程序的多个实例,这就是我禁用它们的原因。我的程序打开一个特定的mime类型。在我的系统(Ubuntu 12.04)中,当我双击其中一个文件时,执行此操作:

/usr/bin/myprogram /path/to/double/clicked/file.myextension

正如我所说,我不喜欢多个实例,因此,如果程序已经运行并且用户选择打开其中一个文件,则会向已经实例发送一个DBus消息,以便小心打开文件。因此,如果有一个已经运行的实例,并且用户选择3个文件用我的程序打开并点击[Enter]按钮,则系统执行:

/usr/bin/myprogram /path/to/double/clicked/file1.myextension
/usr/bin/myprogram /path/to/double/clicked/file2.myextension
/usr/bin/myprogram /path/to/double/clicked/file3.myextension

所有这些实例都会检测已经运行的实例并将打开的文件发送给它。到目前为止没有任何问题。

但是,如果没有已经运行的实例并且用户选择与我的程序一起打开3个文件怎么办?系统将同时调用:

/usr/bin/myprogram /path/to/double/clicked/file1.myextension
/usr/bin/myprogram /path/to/double/clicked/file2.myextension
/usr/bin/myprogram /path/to/double/clicked/file3.myextension

并且每个实例都会意识到已经运行的实例,它将尝试向已经运行的实例发送DBus消息,它将退出。所以,所有3个进程都会做同样的事情,没有任何东西可以运行。

我该如何避免这个问题?

PS:为了检测是否已经在运行实例,我实现了以下代码:

bool already_runs(){
return !system("pidof myprogram | grep \" \" > /dev/null");
}

2 个答案:

答案 0 :(得分:0)

我会使用一些共享内存来存储第一个进程的pid。 QSharedMemory课程将在这里为您提供帮助。

您的程序应该做的第一件事是尝试创建一个共享内存段(使用您自己的组合键)并将您的pid存储在其中。如果创建调用失败,则可以尝试附加到该段。如果成功,那么您可以从中读取原始流程的pid。

编辑:同样,remomber在写入或读取共享内存之前使用lock(),然后在完成后调用unlock()。

答案 1 :(得分:0)

在DBus中执行此操作的标准方法是在总线上获取应用程序的名称;一个实例将赢得比赛并成为正在运行的实例。

但是,您应该能够使用Qt功能执行此操作,该功能将更好地与您的应用程序的其余部分集成;见Qt: Best practice for a single instance app protection