让GTK程序在同一时刻只运行一个实例
前提条件:在windows系统中,采用mingw32编译器,C语言的程序。在主文件的头部定义变量:
int g_lAppInstance __attribute__((section ("shared"), shared)) = 0;
在主函数int main (int argc, char *argv[])的开头部分加入对变量g_lAppInstance 的判断,“0”即没有运行实例,“1”即已经运行一个实例。
if (0 == g_lAppInstance)
{
g_lAppInstance = 1;
//继续运行
}
else
{
return 0; //退出程序
}
在其它编辑语言(如python)或不同的操作系统(如linux)应该如何实现呢?请大家多多指教。
为什么说这个只限在windows中呢?请看网址:http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#index-g_t_0040code_007bshared_007d-variable-attribute-1817
里面有说到:
shared
On Microsoft Windows, in addition to putting variable definitions in a named section, the section can also be shared among all running copies of an executable or DLL. For example, this small program defines shared data by putting it in a named section shared and marking the section shareable:
int foo __attribute__((section ("shared"), shared)) = 0;
int
main()
{
/* Read and write foo. All running
copies see the same value. */
return 0;
}
You may only use the shared attribute along with section attribute with a fully initialized global definition because of the way linkers work. See section attribute for more information.
The shared attribute is only available on Microsoft Windows. 调用ps?查看当前是否有2个自己的进程,如果有,则提示已经启动? 跨平台的解决方案:
一、简单点的,使用unique, 见:Unique 1.1.6 Reference Manua Unique 3.0.0 Reference Manual
二、复杂点的,使用dbus。 正好最近写的程序中也要求单实例运行,代码贴给你看看吧。
......
#ifdef G_OS_WIN32
#include <windows.h>
#include <tlhelp32.h>
#endif
gboolean helloworld_is_running (void)
{
#ifdef G_OS_UNIX
const gchar* uconfig_path;
gchar *path;
FILE *pf;
gchar buffer;
pid_t pid = -1;
uconfig_path = helloworld_dirs_get_user_config_dir();
path = g_build_filename (uconfig_path, "helloworld.pid", NULL);
if (!g_file_test(path, G_FILE_TEST_EXISTS))
{
g_free(path);
return FALSE;
}
pf = g_fopen (path, "r");
if (pf == NULL) {
g_free(path);
return FALSE;
}
g_free(path);
if (fgets (buffer, sizeof (buffer), pf) == NULL)
{
fclose(pf);
return FALSE;
}
fclose(pf);
pid = atoi(buffer);
if (pid == -1 || kill (pid, 0) != 0)
{
return FALSE;
}
return TRUE;
#endif
#ifdef G_OS_WIN32
BOOL bFlag;
gint cnt = -1;
HANDLE hSnapShot = NULL;
PROCESSENTRY32 procentry;
// Get a handle to a Toolhelp snapshot of all processes.
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapShot == INVALID_HANDLE_VALUE)
{
return NULL;
}
// Get the first process' information.
procentry.dwSize = sizeof(PROCESSENTRY32);
bFlag = Process32First(hSnapShot, &procentry);
// While there are processes, keep looping.
while (bFlag) {
// Did we just bump into an NTVDM?
if (_stricmp(procentry.szExeFile, g_get_prgname()) == 0) {
cnt += 1;
}
procentry.dwSize = sizeof(PROCESSENTRY32);
bFlag = Process32Next(hSnapShot, &procentry);
}
if (cnt < 1)
return FALSE;
else
return TRUE;
#endif
}
页:
[1]