代码之家  ›  专栏  ›  技术社区  ›  AareP

正在创建进程之间共享的全局命名计数器

  •  1
  • AareP  · 技术社区  · 15 年前

    顺便说一句,我的流程正在以不同的方式执行。可执行文件:s,不是从某个父进程创建的。操作系统是windows。

    7 回复  |  直到 15 年前
        1
  •  2
  •   SRM    15 年前

        2
  •  1
  •   Greg Domjan    15 年前

    如果不知道有多少潜在的读卡器,你就不能用一个简单的互斥或信号量来知道读卡器什么时候完成,如果不知道每个人都完成了,你就不知道什么时候该重置一个事件来通知下一个读事件。

    MS Windows专用:

    共享段
    一种选择是在共享数据段中放置变量。这意味着相同的变量可以被命名为同一段的所有exe读取(和写入)或者如果你把它放入一个DLL中-加载了共享DLL。

    看到了吗 http://www.codeproject.com/KB/DLL/data_seg_share.aspx 了解更多信息。

    // Note: Be very wary of using anything other than primitive types here!
    #pragma data_seg(".mysegmentname") 
    HWND hWnd = NULL; 
    LONG nVersion = -1;
    #pragma data_seg()
    #pragma comment(linker, "/section:.mysegmentname,rws")
    

    IPC-通讯
    使你的主应用程序成为一个com服务,工作人员可以在其中注册事件,将更改推送到每个事件接收器。

    IPC-双重事件
    创建2个手动重置事件,在任何时候最多有1个事件会被通知,在事件之间交替。信号将立即释放所有读卡器,一旦完成,它们将等待另一个事件。

        3
  •  0
  •   Ali Tarhini    15 年前

    简单的方法是将共享值存储在注册表或文件中,以便所有进程都同意经常检查它。

    最难的方法是使用IPC(进程间通信),我使用的最常用的方法是NamedPipes。这并不难,因为你可以在网上找到很多关于IPC的资源。

        4
  •  0
  •   Community Mohan Dere    9 年前

    如果您不使用*nix,您可以让进程从 named pipe (或套接字),然后在那里编写特定的消息,告诉其他进程它们应该关闭。

    IPC performance: Named Pipe vs Socket

    Windows NAmed Pipes alternative in Linux

        5
  •  0
  •   ur.    15 年前

    使用命名事件对象 带手动复位

    发送过程:

    • 设置事件
    • 睡眠10毫秒

    接收过程:

    • 设置事件时,所有等待进程都将通过
    • 他们读了档案
    • 再等等

    Sleep(10)实际上可能比Sleep(20)耗时更长,但这只会导致另一个循环(再次读取未更改的文件)。

        6
  •  0
  •   ur.    15 年前

    每个读卡器进程都会创建一个命名事件“Global\someuniquestring_%u”,其中%u是它的进程id。如果该事件已发出信号,则读取该文件并执行该操作。

    • 获取名称为'读卡器.exe'(例如)
    • 每个过程都要有id
    • 关闭不再运行的进程的所有句柄。
        7
  •  0
  •   AareP    15 年前

    HANDLE event_trigger;
    __int64 event_last_time;
    vector<string> event_info_args;
    string event_info_file = "event_info.ini";
    
    // On init
    event_trigger = FindFirstChangeNotification(".", false, FILE_NOTIFY_CHANGE_LAST_WRITE);
    event_last_time = stat_mtime_force("event_info.ini");
    
    // On tick
    if (WaitForSingleObject(event_trigger, 0)==0)
    {
        ResetEventTrigger(event_trigger);
    
        if (stat_mtime_changed("event_info.ini", event_last_time))
        {
            FILE* file = fopen_force("event_info.ini");
    
            char buf[4096];
            assert(fgets(buf, sizeof(buf), file));
            split(buf, event_info_args, "\t\r\n");
            fclose(file);
    
            // Process event_info_args here...
    
            HWND wnd = ...;
            InvalidateRect(wnd,0,false);
        }
    }
    
    // On event invokation
    FILE* file = fopen("event_info.ini", "wt");
    assert(file);
    fprintf(file,"%s\t%s\t%d\n",
        "par1", "par2", 1234);
    fclose(file);
    
    stat_mtime_changed("event_info.ini", event_last_time);
    
    
    // Helper functions:
    void ResetEventTrigger()
    {
        do
        {
            FindNextChangeNotification(evt);
        }
        while(WaitForSingleObject(evt, 0)==0);
    }
    FILE* fopen_force(const char* file);
    {
        FILE* f = fopen(file, "rt");
        while(!f)
        {
            Sleep(10+(rand()%100));
            f = fopen(f, "rt");
        }
        assert(f);
        return f;
    }
    __int64 stat_mtime_force(const char* file)
    {
        struct stat stats;
        int res = stat(file, &stats);
        if(res!=0)
        {
            FILE* f = fopen(file, "wt");
            fclose(f);
            res = stat(file, &stats);
        }
        assert(res==0);
        return stats.st_mtime;
    }
    bool stat_mtime_changed(const char* file, __int64& time);
    {
        __int64 newTime = stat_mtime(file);
        if (newTime - time > 0)
        {
            time = newTime;
            return true;
        }
        return false;
    }
    
    推荐文章