C++ 等待另一个进程锁定然后解锁Win32互斥锁

C++ 等待另一个进程锁定然后解锁Win32互斥锁,c++,c,windows,winapi,ipc,C++,C,Windows,Winapi,Ipc,我试图告诉生产者进程何时访问共享的windows互斥体。发生这种情况后,我需要锁定同一个互斥锁并处理相关数据。除了荒谬的循环之外,Windows中是否有内置的方法来实现这一点 我知道,通过在producer进程中创建一个定制的Windows事件,这样做的结果是可行的,但我希望尽可能避免更改此程序代码 我相信(以一种可笑的低效方式)会是这样的(注意:这不是我真正的代码,我知道这有10种不同的错误;我想避免这样做): #包括 int main(){ handleh=CreateMutex(NULL,

我试图告诉生产者进程何时访问共享的windows互斥体。发生这种情况后,我需要锁定同一个互斥锁并处理相关数据。除了荒谬的循环之外,Windows中是否有内置的方法来实现这一点

我知道,通过在producer进程中创建一个定制的Windows事件,这样做的结果是可行的,但我希望尽可能避免更改此程序代码

我相信(以一种可笑的低效方式)会是这样的(注意:这不是我真正的代码,我知道这有10种不同的错误;我想避免这样做):

#包括
int main(){
handleh=CreateMutex(NULL,0,“name”);
如果(!h)返回-1;
int-locked=0;
while(true){
如果(已锁定){
//可以假设它不会被锁定超过一秒钟,但即使锁定了,也应该可以正常工作
if(WaitForSingleObject(h,1000)=等待对象0){
//做处理。。。
锁定=0;
释放互斥(h);
}
//哦,天哪,这太难看了,浪费了这么多CPU。。。
}否则如果(!(锁定=WaitForSingleObject(h,0)=等待超时)){
释放互斥(h);
}
}
返回0;
}

<如果有任何原因,C++有一个更简单的方法,我的代码实际上就是那个。这个例子在C语言中更容易构建。

如果需要高效的共享,您将无法避免更改生产者。你的设计在这方面有根本缺陷

生产者需要能够在数据准备好消费时向消费者发出信号,并确保在数据忙于消费时不会改变数据。单用一个互斥锁无法做到这一点

最好的方法是让生产者在数据准备就绪时设置一个事件,并让消费者在数据已被使用时重置事件。使用互斥锁仅用于同步数据访问,而不是表示数据已准备就绪

#include <Windows.h>

int main()
{
    HANDLE readyEvent = CreateEvent(NULL, TRUE, FALSE, "ready");
    if (!readyEvent) return -1;

    HANDLE mutex = CreateMutex(NULL, FALSE, "name");
    if (!mutex) return -1;

    while(true)
    {
        if (WaitForSingleObject(readyEvent, 1000) == WAIT_OBJECT_0)
        {
            if (WaitForSingleObject(mutex, 1000) == WAIT_OBJECT_0)
            {
                // process as needed...
                ResetEvent(readyEvent);
                ReleaseMutex(mutex);
            }
        }
    }

    return 0;
}
#包括
int main()
{
HANDLE readyEvent=CreateEvent(NULL、TRUE、FALSE、“ready”);
如果(!readyEvent)返回-1;
HANDLE mutex=CreateMutex(NULL,FALSE,“name”);
如果(!mutex)返回-1;
while(true)
{
if(WaitForSingleObject(readyEvent,1000)=等待对象0)
{
if(WaitForSingleObject(互斥,1000)=等待对象0)
{
//根据需要处理。。。
重置事件(readyEvent);
释放互斥(mutex);
}
}
}
返回0;
}
如果不能将生产者更改为使用事件,那么至少要在数据本身中添加一个标志。生产者可以锁定互斥锁,更新数据和标志,并解锁互斥锁。然后,使用者必须定期锁定互斥锁,检查标志并读取新数据(如果设置了标志),重置标志并解锁互斥锁

#include <Windows.h>

int main()
{
    HANDLE mutex = CreateMutex(NULL, FALSE, "name");
    if (!mutex) return -1;

    while(true)
    {
        if (WaitForSingleObject(mutex, 1000) == WAIT_OBJECT_0)
        {
            if (ready)
            {
                // process as needed...
                ready = false;
            }
            ReleaseMutex(mutex);
        }
    }

    return 0;
}
#包括
int main()
{
HANDLE mutex=CreateMutex(NULL,FALSE,“name”);
如果(!mutex)返回-1;
while(true)
{
if(WaitForSingleObject(互斥,1000)=等待对象0)
{
如果(准备就绪)
{
//根据需要处理。。。
就绪=错误;
}
释放互斥(mutex);
}
}
返回0;
}
因此,无论哪种方式,您的逻辑都必须在生产者和消费者中进行调整

否则,如果您根本无法更改生产商,则您别无选择,只能单独更改消费者,以简单地检查数据的更改:

#include <Windows.h>

int main()
{
    HANDLE mutex = CreateMutex(NULL, 0, "name");
    if (!mutex) return -1;

    while(true)
    {
        if (WaitForSingleObject(mutex, 1000) == WAIT_OBJECT_0)
        {
            // check data for changes
            // process new data as needed
            // cache results for next time...
            ReleaseMutex(mutex);
        }
    }

    return 0;
}
#包括
int main()
{
HANDLE mutex=CreateMutex(NULL,0,“name”);
如果(!mutex)返回-1;
while(true)
{
if(WaitForSingleObject(互斥,1000)=等待对象0)
{
//检查数据是否有更改
//根据需要处理新数据
//缓存结果以备下次使用。。。
释放互斥(mutex);
}
}
返回0;
}

很棘手。我将回答一个潜在的问题:什么时候写入内存

这可以通过四步解决方案观察到:

  • 在监视的进程中插入DLL
  • STATUS\u GUARD\u PAGE\u违规添加向量异常处理程序
  • 在2MB内存范围内设置保护页位(找到它可能是一个挑战)
  • 从向量异常处理程序中,通知您的流程并重新建立保护位(这是一次性的)

  • 如果图像总是被完全重写,您可能只需要一个保护页。

    也可以使用事件(
    CreateEvent
    ),制作者可以设置该事件,让您的其他进程知道是时候处理数据了。实际上,根据制作者的编写方式,您的代码可能会死锁。这是一种根本性的方法。您不仅会烧掉100%的内核,还可能完全看不到另一个线程实际获取并释放互斥锁。这是没有出路的,你需要重新设计你的方法。我知道这种方法很糟糕。活动会100%好。但是我想完全避免更改生产者代码。我的问题可能措辞不好。我想问的是,是否有一种方法可以判断何时锁定/解锁互斥体,而不必像我给出的示例那样做一些愚蠢的事情。您可以检查“关联数据”以查看是否有任何变化,而不是检查互斥体吗?您已经有了“do processing”,所以我假设您可以访问生成的数据。问题是,数据的形式是什么?您能否检测到是否产生了新数据?如果你认为已经产生了新的数据,你可以获得互斥并处理数据。因此,我听到的是,如果我不想愚蠢地改变生产者,我无法避免。知道了。你是怎么说用一个信号量来支持多个客户端的事件(如果我改变了生产者,我也可以做得很好)?