C++ 如何使用互斥锁自动交换3个进程?

C++ 如何使用互斥锁自动交换3个进程?,c++,windows,visual-studio,C++,Windows,Visual Studio,我有3个程序,每个程序需要在一个文件中写入1000次。互斥体必须在每10次写入后切换程序 #include "stdafx.h" #include <Windows.h> #include <fstream> #include <iostream> using namespace std; HANDLE ghMutex; void write() { ghMutex = OpenMutex(SYNCHRONIZE, false, (LPTSTR)"

我有3个程序,每个程序需要在一个文件中写入1000次。互斥体必须在每10次写入后切换程序

#include "stdafx.h"
#include <Windows.h>
#include <fstream>
#include <iostream>
using namespace std;
HANDLE ghMutex;


void write()
{
    ghMutex = OpenMutex(SYNCHRONIZE, false, (LPTSTR)"WriteData");
    for (int i=0; i<100; i ++) { 
            WaitForSingleObject(ghMutex, INFINITE);
            ofstream f1("c:\\write.txt", ios_base::app);
            for (int j=0; j<10; j++)
                    f1 << 2;        
            ReleaseMutex(ghMutex);
            f1.close();
            Sleep(100);
    }
}

void main(){
write();
}
#包括“stdafx.h”
#包括
#包括
#包括
使用名称空间std;
处理互斥;
无效写入()
{
ghMutex=OpenMutex(同步,false,(LPTSTR)“WriteData”);

for(int i=0;i在任何进程中是否
ghMutex
有效?在
OpenMutex()
WaitForSingleObject()之后
GetLastError()
返回的值如何

您需要先在其中一个进程中创建互斥体,然后其他进程才能打开它。幸运的是,
CreateMutex
完全满足您的需要:如果互斥体不存在,它将创建互斥体;如果存在,它将打开互斥体


您可能希望在之前(而不是之后)关闭流释放互斥锁,以便在其他进程开始写入之前刷新缓存数据。

从您的描述中不清楚您希望程序如何运行。是否希望程序确保进程交替,如果是,是否希望循环类型排序(例如,过程1,然后是过程2,然后是过程3,然后是过程1)

但是,很明显,您当前的互斥体用法是不正确的。首先,至少有一个进程必须调用
CreateMutex()
,才能实际创建互斥体(否则没有要打开的互斥体)。因为的文档中说:

如果
lpName
与现有命名互斥对象的名称匹配,此函数将请求
mutex\u ALL\u访问权

假设请求更多访问权限对您来说不是问题(很少是),那么您可以让所有实例调用
CreateMutex()
,确保它们都共享相同的互斥体,并且以最先创建的为准

这是一个简单的示例,其中的进程以不可预测的顺序交替(允许重复),但一行正确写入文件10次,而不会被并发写入程序中断

#include <Windows.h>
#include <conio.h>
#include <iostream>
#include <fstream>

int main ( int, char ** )
{
    // get a named mutex.  open the same mutex as other
    // concurrent instances.
    const ::HANDLE mutex = ::CreateMutexW(0, FALSE, L"Fubar");
    if (mutex == INVALID_HANDLE_VALUE)
    {
        const ::DWORD error = ::GetLastError();
        std::cerr
            << "Could not open mutex (" << error << ")."
            << std::endl;
        return (EXIT_FAILURE);
    }

    // open the input file.  notice the flags, you need to make
    // sure the 2nd process doesn't overwrite whatver the first
    // wrote, etc.
    std::ofstream file("foo.txt", std::ios::app);
    if (!file.is_open())
    {
        std::cerr
            << "Could not open file."
            << std::endl;
        return (EXIT_FAILURE);
    }

    // wait for user to unblock after launch.  this gives time
    // to start concurrent processes before we write to the
    // file.
    ::getch();

    // not sure how your application goes, but lets just
    // repeatedly write to the file until we're fed up.
    for (int j=0; j < 100; ++j)
    {
        // lock the mutex around the code that writes to the
        // file in a loop.
        ::WaitForSingleObject(mutex, INFINITE);
        for (int i=0; i < 10; ++i) {
            file << "process " << ::GetCurrentProcessId() << std::endl;
        }
        ::ReleaseMutex(mutex);

        // slow down so the application doesn't finish before we
        // unblock concurrent instances.
        ::Sleep(100);
    }

    // don't forget to clean up!
    ::CloseHandle(mutex);
}
#包括
#包括
#包括
#包括
int main(int,char**)
{
//获取命名的互斥体。打开与其他互斥体相同的互斥体
//并发实例。
const::HANDLE mutex=::CreateMutexW(0,FALSE,L“Fubar”);
if(互斥==无效的\u句柄\u值)
{
常量::DWORD错误=::GetLastError();
标准:cerr

你忘了提到这是家庭作业&也是你解决它的努力。我不认为这是家庭作业;教授会知道(我希望!)互斥不能像这样工作。@MSalters:并不意味着学生和他们的教授一样理解这个概念;-)您是否希望有一个特定的执行顺序?即p1应该写入,然后p2,然后p3,等等?@user1173543:不是这样。您必须自己实现它;有几种方法可以实现。例如,您可以为每个进程分配一个事件,每个进程在完成后会向下一个进程发送事件信号。或者您可以使用共享内存中的变量,与变量更改时要激活的事件相耦合。您应该发布另一个问题,专门针对该问题:)怎么把他们联系起来?他们在一起写。我想他们彼此都看不见other@user1173543:只需将对
OpenMutex
的调用替换为对
CreateMutex
的调用,并检查返回值:-)。您还应该在释放互斥锁之前关闭流。我重命名为CreateMutex并在释放前关闭流。这没有帮助。@AndréCaron谢谢!!!它真的很有效!请回答,互斥可以进行循环式排序吗?@André:+1,你弥补了我的懒惰:)@user1173543:用一个互斥无法实现这一点。你可能可以用每个进程一个互斥来实现循环排序,每个进程都对自己的互斥和释放进行锁定在完成编写时对其进行ses。如果后继对象(并且只有正确的后继对象)正在等待该互斥对象,则您可能会实现类似的操作。但是,这是一个更复杂的设置,例如可能有点复杂。这是留给读者的练习;-)