who9394 发表于 2011-5-9 21:28:20

让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.

ACTom 发表于 2011-5-10 01:37:42

调用ps?查看当前是否有2个自己的进程,如果有,则提示已经启动?

yetist 发表于 2011-5-10 04:35:03

跨平台的解决方案:
一、简单点的,使用unique, 见:Unique 1.1.6 Reference Manua Unique 3.0.0 Reference Manual
二、复杂点的,使用dbus。

yetist 发表于 2011-9-25 09:40:22

正好最近写的程序中也要求单实例运行,代码贴给你看看吧。

......
#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]
查看完整版本: 让GTK程序在同一时刻只运行一个实例