2017-01-29 69 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"); 

您不必將字符串硬編碼爲信號量名稱。父進程可以每次創建一個唯一的名稱,然後將該名稱(例如命令行參數)傳遞給子進程。這將允許您的程序的多個實例與子進程進行合作。