拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 无法从另一个行程C 打开现有的信号量

无法从另一个行程C 打开现有的信号量

白鹭 - 2022-02-22 2090 0 0

我正在尝试从另一个行程中获取现有的信号量。要创建信号量,我使用:

Semaphore(std::string name, int startState) {
    name = "Global\\"   name;
    Sem = OpenSemaphore(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, true, (LPCWSTR)name.c_str());
    int s = (startState > 0);
    if (Sem == NULL) {
        Sem = CreateSemaphore(NULL, s, 1, (LPCWSTR)name.c_str());
    }
}

在第一个程序中正确创建了信号量。GetLastError() 回传 0。在第二个程序中,OpenSemaphore 回传 NULL。并且 GetLastError() 回传 2。我试图仅通过“名称”获取信号量 - 没有“全域\”,但它得到了相同的结果。请帮忙)

uj5u.com热心网友回复:

如果您觉得需要使用 C 风格的强制转换(如 中(LPCWSTR)name.c_str()),您应该将其视为您做错了什么的标志。

就像您在这里所做的那样:std::string是一个字符(即char)字符串,而您使用字符( wchar_t) 函式。这意味着名称不会是您所期望的。

如果继续使用std::string,则必须使用“ANSI”函式(例如CreateSemaphoreA)。否则切换到std::wstring哪个使用宽字符。

uj5u.com热心网友回复:

@SomeProgrammerDude 的回答解释了您所看到的错误的原因(字符编码不匹配)。

我只想指出,在解决该问题后,您的代码中仍然存在竞争条件。

如果你想打开一个现有的信号量(或任何其他型别的命名内核物件),如果它不存在就创建它,那么不要浪费时间打开它,只需无条件地创建它,例如:

Semaphore(std::string name, int startState) {
    name = "Global\\"   name;
    int s = (startState > 0);
    Sem = CreateSemaphoreA(NULL, s, 1, name.c_str());
}

如果物件已经存在,您将获得现有物件的句柄,而输入自变量将被忽略。否则,您将获得使用自变量初始化的新物件的句柄。GetLastError()如果需要,可用于告诉您物件是已经存在还是重新创建。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *