我正在尝试从另一个行程中获取现有的信号量。要创建信号量,我使用:
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 评论