无法从另一个进程 C++ 打开现有信号量
Can't open existing semaphore from another process C++
我正在尝试从另一个进程获取现有信号量。为了创建信号量,我使用了:
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() returns 0。在第二个进程中,OpenSemaphore returns NULL。和 GetLastError() returns 2。
我试图仅通过“名称”获取信号量 - 没有“Global\”,但它得到了相同的结果。请帮忙)
如果您觉得需要使用 C 风格的转换(例如 (LPCWSTR)name.c_str()
),您应该将其视为您做错事的标志。
就像你在这里所做的那样:std::string
是一个 narrow 字符(即 char
)字符串,而您使用 wide 字符 (wchar_t
) 函数。这意味着名称将不是您所期望的。
如果继续使用 std::string
,则必须使用“ANSI”函数(例如 CreateSemaphoreA
)。否则切换到使用宽字符的 std::wstring
。
解释了您看到的错误的原因(字符编码不匹配)。
我只想指出,在解决该问题后,您的代码中仍然存在竞争条件。
如果你想打开一个现有的信号量(或任何其他类型的命名内核对象),如果它不存在就创建它,那么不要浪费时间打开它,只需无条件地创建它,例如:
Semaphore(std::string name, int startState) {
name = "Global\" + name;
int s = (startState > 0);
Sem = CreateSemaphoreA(NULL, s, 1, name.c_str());
}
如果对象已经存在,您将获得现有对象的句柄,输入参数将被忽略。否则,您将获得一个使用您的参数初始化的新对象的句柄。如果需要,GetLastError()
可用于告诉您对象是否已存在或重新创建。
我正在尝试从另一个进程获取现有信号量。为了创建信号量,我使用了:
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() returns 0。在第二个进程中,OpenSemaphore returns NULL。和 GetLastError() returns 2。 我试图仅通过“名称”获取信号量 - 没有“Global\”,但它得到了相同的结果。请帮忙)
如果您觉得需要使用 C 风格的转换(例如 (LPCWSTR)name.c_str()
),您应该将其视为您做错事的标志。
就像你在这里所做的那样:std::string
是一个 narrow 字符(即 char
)字符串,而您使用 wide 字符 (wchar_t
) 函数。这意味着名称将不是您所期望的。
如果继续使用 std::string
,则必须使用“ANSI”函数(例如 CreateSemaphoreA
)。否则切换到使用宽字符的 std::wstring
。
我只想指出,在解决该问题后,您的代码中仍然存在竞争条件。
如果你想打开一个现有的信号量(或任何其他类型的命名内核对象),如果它不存在就创建它,那么不要浪费时间打开它,只需无条件地创建它,例如:
Semaphore(std::string name, int startState) {
name = "Global\" + name;
int s = (startState > 0);
Sem = CreateSemaphoreA(NULL, s, 1, name.c_str());
}
如果对象已经存在,您将获得现有对象的句柄,输入参数将被忽略。否则,您将获得一个使用您的参数初始化的新对象的句柄。如果需要,GetLastError()
可用于告诉您对象是否已存在或重新创建。