2017-01-29 22 views
0

我使用下面的代码从微软作为一个模板:如何使用Windows API直接“分配”进程到信号量?

#include <windows.h> 
#include <stdio.h> 

#define MAX_SEM_COUNT 10 
#define THREADCOUNT 12 

HANDLE ghSemaphore; 

DWORD WINAPI ThreadProc(LPVOID); 

int main(void) 
{ 
    HANDLE aThread[THREADCOUNT]; 
    DWORD ThreadID; 
    int i; 

    // Create a semaphore with initial and max counts of MAX_SEM_COUNT 

    ghSemaphore = CreateSemaphore( 
     NULL,   // default security attributes 
     MAX_SEM_COUNT, // initial count 
     MAX_SEM_COUNT, // maximum count 
     NULL);   // unnamed semaphore 

    if (ghSemaphore == NULL) 
    { 
     printf("CreateSemaphore error: %d\n", GetLastError()); 
     return 1; 
    } 

    // Create worker threads 

    for(i=0; i < THREADCOUNT; i++) 
    { 
     aThread[i] = CreateThread( 
        NULL,  // default security attributes 
        0,   // default stack size 
        (LPTHREAD_START_ROUTINE) ThreadProc, 
        NULL,  // no thread function arguments 
        0,   // default creation flags 
        &ThreadID); // receive thread identifier 

     if(aThread[i] == NULL) 
     { 
      printf("CreateThread error: %d\n", GetLastError()); 
      return 1; 
     } 
    } 

    // Wait for all threads to terminate 

    WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE); 

    // Close thread and semaphore handles 

    for(i=0; i < THREADCOUNT; i++) 
     CloseHandle(aThread[i]); 

    CloseHandle(ghSemaphore); 

    return 0; 
} 

DWORD WINAPI ThreadProc(LPVOID lpParam) 
{ 

    // lpParam not used in this example 
    UNREFERENCED_PARAMETER(lpParam); 

    DWORD dwWaitResult; 
    BOOL bContinue=TRUE; 

    while(bContinue) 
    { 
     // Try to enter the semaphore gate. 

     dwWaitResult = WaitForSingleObject( 
      ghSemaphore, // handle to semaphore 
      0L);   // zero-second time-out interval 

     switch (dwWaitResult) 
     { 
      // The semaphore object was signaled. 
      case WAIT_OBJECT_0: 
       // TODO: Perform task 
       printf("Thread %d: wait succeeded\n", GetCurrentThreadId()); 
       bContinue=FALSE;    

       // Simulate thread spending time on task 
       Sleep(5); 

       // Release the semaphore when task is finished 

       if (!ReleaseSemaphore( 
         ghSemaphore, // handle to semaphore 
         1,   // increase count by one 
         NULL))  // not interested in previous count 
       { 
        printf("ReleaseSemaphore error: %d\n", GetLastError()); 
       } 
       break; 

      // The semaphore was nonsignaled, so a time-out occurred. 
      case WAIT_TIMEOUT: 
       printf("Thread %d: wait timed out\n", GetCurrentThreadId()); 
       break; 
     } 
    } 
    return TRUE; 
} 

我要去适应它,而不是作为线程确定旗语如何填充的,它是由程序完成的,也就是说,如果有进程正在运行,并且/或者它们的任何哈希都没有关闭,那么信号量就会被填充,事实上,我通过使用这个新函数改变了线程函数的工作方式。

DWORD WINAPI ThreadProc(LPVOID lpParam) 
{ 

    // lpParam not used in this example 
    UNREFERENCED_PARAMETER(lpParam); 

    DWORD dwWaitResult; 
    BOOL bContinue=TRUE; 

    STARTUPINFO si; 
    PROCESS_INFORMATION pi; 
    memset(&si,0,sizeof(si)); 
    si.cb=sizeof(si); 

    while(bContinue) 
    { 
     // Try to enter the semaphore gate. 

     dwWaitResult = WaitForSingleObject( 
      ghSemaphore, // handle to semaphore 
      0L);   // zero-second time-out interval 

     CreateProcess("arbol.exe",NULL,NULL,NULL,0,0,NULL,NULL,&si,&pi);  
     WaitForSingleObject(pi.hProcess,INFINITE); 
     CloseHandle(pi.hProcess); 
     CloseHandle(pi.hThread); 

     switch (dwWaitResult) 
     { 
      // The semaphore object was signaled. 
      case WAIT_OBJECT_0: 
       // TODO: Perform task 
       printf("Thread %d: wait succeeded\n", GetCurrentThreadId()); 
       bContinue=FALSE;    

       // Simulate thread spending time on task 
       Sleep(5); 

       // Release the semaphore when task is finished 

       if (!ReleaseSemaphore( 
         ghSemaphore, // handle to semaphore 
         1,   // increase count by one 
         NULL))  // not interested in previous count 
       { 
        printf("ReleaseSemaphore error: %d\n", GetLastError()); 
       } 
       break; 

      // The semaphore was nonsignaled, so a time-out occurred. 
      case WAIT_TIMEOUT: 
       printf("Thread %d: wait timed out\n", GetCurrentThreadId()); 
       break; 
     } 
    } 
    return TRUE; 
} 

随着的是,虽然什么决定了信号量的填充是单线程的,在实际意义上它是由该方法的手柄的完整执行和关闭来确定。

但是,这看起来是一个蹩脚的方式来解决这个问题,我敢打赌这样做可能会给未来的问题,如果需要额外的东西从这些过程。

我该如何创建一个信号量,才能真正确定信号量的填充是什么过程?为了澄清,这将是一个可能的解决方案,我不认为这是可能的。

让我们考虑一下,你可以通过这样的创建过程:

aThread[i] = CreateProcess( 
        NULL,  // default security attributes 
        0,   // default stack size 
        (LPTHREAD_START_ROUTINE) ThreadProc, 
        NULL,  // no thread function arguments 
        0,   // default creation flags 
        &ThreadID); // receive thread identifier 

然后LPTHREAD_START_ROUTINE将是其工作但过程相当的。

信号量应该支持Interprocess Synchronization在Windows API中,但我找不到任何具体使用进程的示例,我不知道它是如何完成的。

关于如何实现我想要的任何想法?

问候。

回答

1

你想要一个命名的信号量。每个进程通过使用相同名称创建它来共享信号量。

创建一个指定的信号量。和你一样有前,但最后一个参数被传递给它的字符串:

HANDLE hSemaphore = CreateSemaphore(NULL, 
            MAX_SEM_COUNT, 
            MAX_SEM_COUNT, 
            L"TheSemaphoreForMyApp"); 

子进程,一旦被启动,可以连接到相同的信号,并通过使用OpenSemaphore得到它的句柄。

HANDLE hSemaphore = OpenSemaphore(EVENT_ALL_ACCESS, 
            FALSE, 
            L"TheSemaphoreForMyApp"); 

您不必将字符串硬编码为信号量名称。父进程可以每次创建一个唯一的名称,然后将该名称(例如命令行参数)传递给子进程。这将允许您的程序的多个实例与子进程进行合作。