c++ - Windows 信号量

标签 c++ windows winapi process semaphore

我需要实现一个程序,它使用信号量将打开的记事本窗口的数量限制为 10 个。我在 WM_INITDIALOG 中创建了一个信号量

    semafor = CreateSemaphore(0, 1, 10, "semaphore");

每次我点击按钮打开一个新窗口时,我都会打开那个信号灯。然而,这并不能阻止我打开 10 个以上的窗口。

这是我在对话框中单击按钮打开新窗口时的代码:

case WM_COMMAND:
    switch (LOWORD(wParam)) {
        case ID_OK: 

            semafor = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, "semaphore");
            if (semafor == NULL) {
                printf("Eroare deschidere semafor empty: %d \n", GetLastError());
                ExitProcess(1);
            }

            BOOL b = CreateProcess("C:\\Windows\\System32\\notepad.exe",
                NULL, NULL, NULL, TRUE, 0, NULL, NULL,
                &si, &pi);

            process[++i] = GetCurrentProcess();

            if (b) {
                dwWaitForChild = WaitForInputIdle(pi.hProcess, 2000);
                switch (dwWaitForChild) {
                case 0:
                    printf("Procesul fiu este ready!\n");
                    break;
                case WAIT_TIMEOUT:
                    printf("Au trecut 2 sec. si procesul fiu nu este ready!\n");
                    break;
                case 0xFFFFFFFF:
                    printf("Eroare!\n");
                    break;
                }

                WaitForMultipleObjects(i, process, TRUE, INFINITE);

                iRasp = MessageBox(NULL, "Terminam procesul fiu?", "Atentie!", MB_YESNO);
                if (iRasp == IDYES) {
                    if (TerminateProcess(pi.hProcess, 2)) {

                        DWORD dwP;

                        GetExitCodeProcess(pi.hProcess, &dwP);
                        printf("Codul de terminare al procesului fiu: %d\n", dwP);
                        ReleaseSemaphore(semafor, 1, NULL);
                        CloseHandle(pi.hProcess);
                        printf("\nProcesul fiu a fost terminat cu succes\n");
                    }
                    else {
                        //tiparim mesajul de eroare 
                        TCHAR buffer[80];
                        LPVOID lpMsgBuf;
                        DWORD dw = GetLastError();

                        FormatMessage(
                            FORMAT_MESSAGE_ALLOCATE_BUFFER |
                            FORMAT_MESSAGE_FROM_SYSTEM,
                            NULL,
                            dw,
                            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                            (LPTSTR)&lpMsgBuf,
                            0, NULL);

                        wsprintf(buffer, "TerminateProcess() a esuat cu eroarea %d: %s",
                            dw, lpMsgBuf);

                        MessageBox(NULL, buffer, "Eroare!", MB_OK);

                        LocalFree(lpMsgBuf);
                    }
                } // rasp YES

            }
            else
                printf("Eroare la crearea procesului fiu!\n");

            return TRUE;
        }
        break;
    }
    return FALSE;
}

最佳答案

您永远不会等待(或信号量逻辑中的 P)信号量。

检查 winapi example关于如何使用信号量。在他们的示例中,他们使用 WaitForSingleObject。您只使用 OpenSemaphore ,它只为您提供信号量句柄,因此您可以在多个进程中使用它,然后如果您想减少它的值并在它为 0 时等待/超时,则需要实际等待它.

在打开信号量之后和尝试打开记事本实例之前,你应该做这样的事情:

// Try to enter the semaphore gate.

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

关于c++ - Windows 信号量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47290226/

相关文章:

c++ - C++ 中 placement new 执行的完整操作列表是什么?

async_receive 和 async_send 处理程序中的 C++ Boost.Asio 错误

windows - 尝试通过 Pcap.net 连接到某人时如何防止 Windows 发送 RST 数据包?

linux - ansible 2.3> 在检查 Windows 主机时,错误 : Thread failed to start

c++ - Visual C++ 和 *nix 环境下的编译差异

C++ 在 for 循环中使用预先计算的限制器

c++ - 父类和子类之间的静态变量

c++ - QNetworkReply 没有数据

c++ - 如何从加载程序 DLL 获取函数地址?

c++ - 将 LPTSTR 转换为长整型