名为信号的窗口未锁定
Windows Named Semaphore Not Getting Locked
我正在开发带有Windows API C库的C 类。
我正在使用信号量进行任务,假设我有两个过程:
Processa有两个信号量:
全局 processa_receiving_semaphore
全局 processa_waiting_semaphore
ProcessB有两个信号量:
全局 processb_receiving_semaphore
全局 processb_waiting_semaphore
我在每个过程中都有两个线程:
在Processa中发送线程:
等待"全局 processb_waiting_semaphore"
//做某事
信号" global processb_receiving_semaphore"
在ProcessB上接收线程:
等待"全局 processb_receiving_semaphore"
//做某事
信号" global processb_waiting_semaphore
我删除了发布"全局 processb_waiting_semaphore"的所有代码。但仍然可以获取。在该信号量上调用WaitForSingleObject
始终返回成功的等待和立即。我尝试将超时时间设置为0,但它仍然可以获取信号量,而没有任何释放。
接收信号量具有initial count = 0
和max count = 1
,而等待信号量具有initial count = 1
和max count = 1
。
在接收信号量上调用WaitForSingleObject
的功能很好,并且块块由另一个过程释放。问题在于等待信号量,我不知道原因。代码很大,我确保了信号量的名称已正确设置。
这是一个常见问题吗?如果您需要更多说明,请评论,我将修改帖子。
编辑:添加代码:
接收器信号量:
bool intr_process_comm::create_rcvr_semaphores()
{
std::cout << "n Creating semaphore: " << "Global\" << this_name << "_rcvr_sem";
rcvr_sem = CreateSemaphore(NULL, 0, 1, ("Global\" + this_name + "_rcvr_sem").c_str());
std::cout << "n Creating semaphore: " << "Global\" << this_name << "_wait_sem";
wait_sem = CreateSemaphore(NULL, 1, 1, ("Global\" + this_name + "_wait_sem").c_str());
return (rcvr_sem && wait_sem);
}
发件人信号量:
// this sender connects to the wait semaphore in the target process
sndr_sem = OpenSemaphore(SEMAPHORE_MODIFY_STATE, FALSE, ("Global\" + target_name + "_wait_sem").c_str());
// this target connects to the receiver semaphore in the target process
trgt_sem = OpenSemaphore(SEMAPHORE_MODIFY_STATE, FALSE, ("Global\" + target_name + "_rcvr_sem").c_str());
DWORD intr_process_locking::wait(unsigned long period)
{
return WaitForSingleObject(sndr_sem, period);
}
void intr_process_locking::signal()
{
ReleaseSemaphore(trgt_sem, 1, 0);
}
接收线程功能:
void intr_process_comm::rcvr_thread_proc()
{
while (conn_state == intr_process_comm::opened) {
try {
// wait on rcvr_semaphore for an infinite time
WaitForSingleObject(rcvr_sem, INFINITE);
if (inner_release) // if the semaphore was released within this process
return;
// once signaled by another process, get the message
std::string msg_str((LPCSTR)hmf_mapview);
// signal one of the waiters that want to put messages
// in this process's memory area
//
// this doesn't change ANYTHING in execution, commented or not..
//ReleaseSemaphore(wait_sem, 1, 0);
// put this message in this process's queue
Msg msg = Msg::from_xml(msg_str);
if (msg.command == "connection")
process_connection_message(msg);
in_messages.enQ(msg);
//std::cout << "n Message: n"<< msg << "n";
}
catch (std::exception e) {
std::cout << "n Ran into trouble getting the message. Details: " << e.what();
}
}
}
发送线程功能:
void intr_process_comm::sndr_thread_proc()
{
while (conn_state == intr_process_comm::opened ||
(conn_state == intr_process_comm::closing && out_messages.size() > 0)
) {
// pull a message out of the queue
Msg msg = out_messages.deQ();
if (connections.find(msg.destination) == connections.end())
connections[msg.destination].connect(msg.destination);
if (connections[msg.destination].connect(msg.destination)
!= intr_process_locking::state::opened) {
blocked_messages[msg.destination].push_back(msg);
continue;
}
// THIS ALWAYS GETS GETS WAIT_OBJECT_0 RESULT
DWORD wait_result = connections[msg.destination].wait(wait_timeout);
if (wait_result == WAIT_TIMEOUT) { // <---- THIS IS NEVER TRUE
out_messages.enQ(msg);
continue;
}
// do things here
// release the receiver semaphore in the other process
connections[msg.destination].signal();
}
}
澄清一些事情:
发件人中的 trgt_sem
是接收器中的 rcvr_sem
。
`sndr_sem'是'wait_sem;在接收器中。
用于调用 WaitForSingleObject
带有一些句柄:
手柄必须具有
SYNCHRONIZE
访问权利。
但是,您只需 SEMAPHORE_MODIFY_STATE
访问。使用此访问,可以调用ReleaseSemaphore
(此句柄必须具有 SEMAPHORE_MODIFY_STATE
访问权利),但请致电WaitForSingleObject
失败,结果WAIT_FAILED
。在此之后,请致电GetLastError()
,必须返回ERROR_ACCESS_DENIED
。
因此,如果我们要呼叫ReleaseSemaphore
和任何等待功能 - 我们需要在手柄上具有 SEMAPHORE_MODIFY_STATE | SYNCHRONIZE
访问。因此需要使用代码
OpenSemaphore(SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, )
当然,总是检查API返回值和错误代码可以节省很多时间
如果将超时设置为0 waitforsingleobject将始终立即返回,那么成功的waitforsingleobject将返回wait_object_0(恰好具有值为0),wfso并不像大多数API一样,大多数API都指示了所指示的大多数API通过非零返回。
- 如何在Qt窗口小部件中使用QStringView(或QStringRef)
- 如何找到锁定Linux futex的C++行
- 问:如何使用C++中的按钮从窗口打开窗口
- G锁定铸造到基础上会释放模拟行为
- SDL 窗口不会弹出
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 如何在cpp文件之间切换窗口?在Qt中
- QuadTree只在窗口的右上角绘制
- 如何检查线程是否锁定
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 如何在C++中找到active directory中禁用和锁定的窗口帐户
- 我应该在锁定TBitmap画布后解锁它吗
- 处理闪烁窗口事件
- 名为信号的窗口未锁定
- 窗口 - 锁定程序背景
- 在没有锁定应用程序的情况下生成控制台窗口
- 系统范围的热键快捷方式(Windows/Qt):防止窗口锁定
- QT 关闭窗口 QTest 在锁定线程中
- C++在WM6.1上锁定标签栏,但也锁定窗口键
- 显示锁定应用程序所有窗口的MessageBox