【问题标题】:Issue with MailSlot in winapi, ReadFile doesnt read value from mailslotwinapi 中的 MailSlot 问题,ReadFile 不从 mailslot 读取值
【发布时间】:2020-07-22 06:26:35
【问题描述】:

我正在尝试设置一个邮槽,我可以写入我的值并从中读取。就我而言,我有两个相互配合的进程。第一个进程从用户那里获取信息并将信息发送到另一个进程以计算结果。第二个进程应该从邮槽读取数据,但是当调用函数 ReadFile() 时进程被冻结并且我什么也没得到。 我试图找到有关邮槽的一些信息,但没有得到我想要的。谁知道这个邮槽并且可以帮助我?

第一个过程:

int main()
{
    HANDLE m = CreateMutex(NULL, FALSE, L"MyMutex");
    if (m == 0)
        return -1;

    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    if (CreateProcess(L"c:\\Users\\user\\Desktop\\Lab3\\Procces1\\Debug\\Procces1.exe", NULL,
        NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi) == TRUE) {

        bool flagEnd = true;
        double a,b,c;

        HANDLE file = CreateFile(L"\\\\.\\mailslot\\c:\\Users\\user\\Desktop\\Lab3\\mail", GENERIC_WRITE|GENERIC_READ,
            FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (file == 0)
            return -1;

        while (true) {
            WaitForSingleObject(m, INFINITE);
            cout << "Please enter A and B values\n";
            cout << "A = ";
            cin >> a;
            cout << "B = ";
            cin >> b;
            WriteFile(file, &a, sizeof(double), NULL, NULL);
            WriteFile(file, &b, sizeof(double), NULL, NULL);
            ReleaseMutex(m);
        }

        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        CloseHandle(m);
    }
    else {
        cout << "Process has not been created\n";
    }
    return 0;
}

第二道工序:

int main()
{
    HANDLE mut = OpenMutex(MUTEX_ALL_ACCESS, TRUE, L"MyMutex");
    if (mut == 0)
        return -1;

    HANDLE mail = CreateMailslot(L"\\\\.\\mailslot\\c:\\Users\\user\\Desktop\\Lab3\\mail", 0, MAILSLOT_WAIT_FOREVER, NULL);
    if (mail == 0)
        return -1;

    double a, b, c;
    DWORD byte;
    while (true) {
        WaitForSingleObject(mut, INFINITE);
        cout << "Reading\n"; //this works
        ReadFile(mail, &a, sizeof(double), &byte, NULL);  
        ReadFile(mail, &b, sizeof(double), &byte, NULL);  
        cout << "I have read " << a << " " << b << endl;  //this message doesn't send
        ReleaseMutex(mut);                                //and therefore releasemutex wont be called
    }
    return 0;
}

【问题讨论】:

  • ReadFile 不会冻结。当您为最终参数传递 nullptr 时,这只是一个阻塞调用。当然,如果您使用正确的错误处理,您将能够更好地理解您的问题。据我所知,您使用的唯一错误处理是错误的。这不会很成功。开始here
  • CreateFile/CreateMailslot 失败返回不是 0 而是 INVALID_HANDLE_VALUE。所以你的条件不正确。 CreateFile 用于邮槽 - 在这里你有提升条件 - 所有子进程的速度更快但尚未完成(甚至没有开始)调用 CreateMailslot
  • 你不需要任何静音 - 为什么?什么结束写入数据,另一个读取。
  • @RbMm 这是大学的任务。我知道这看起来很奇怪

标签: c++ multithreading c++11 winapi c++14


【解决方案1】:

注意:使用错误的值进行错误检查。使用if (file == INVALID_HANDLE_VALUE) 而不是if (file == 0)。 (如果你还没有做,建议为所有函数调用添加错误检查。ReadFileWriteFile等)

并删除Procces1.exe(我在这里没有看到它的用法)部分。先启动第二个进程(创建并读取Mailslot进程),再启动第一个进程(写入mailslot进程),运行,得到如下结果:

修改后的代码:

第一个过程:

int main()
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    HANDLE m = CreateMutex(NULL, FALSE, L"MyMutex");
    if (m == 0)
        return -1;

    bool flagEnd = true;
    double a, b, c;

    HANDLE file = CreateFile(L"\\\\.\\mailslot\\c:\\Users\\user\\Desktop\\Lab3\\mail", GENERIC_WRITE | GENERIC_READ,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (file == INVALID_HANDLE_VALUE)
        return -1;

    while (true) {
        cout << "Please enter A and B values\n";
        cout << "A = ";
        cin >> a;
        cout << "B = ";
        cin >> b;
        WriteFile(file, &a, sizeof(double), NULL, NULL);
        WriteFile(file, &b, sizeof(double), NULL, NULL);
        ReleaseMutex(m);
    }

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    CloseHandle(m);

    return 0;
}

第二道工序:

int main()
{
    HANDLE mail = CreateMailslot(L"\\\\.\\mailslot\\c:\\Users\\user\\Desktop\\Lab3\\mail", 0, MAILSLOT_WAIT_FOREVER, NULL);
    if (mail == INVALID_HANDLE_VALUE)
        return -1;

    HANDLE mut = NULL;

    cout << "Waiting for another process write something to mailslot\n"; //this works
    while (NULL == mut)
    {
        mut = OpenMutex(MUTEX_ALL_ACCESS, TRUE, L"MyMutex");
        Sleep(10);
        cout << ".";
    }
    cout << "\n";

    double a, b, c;
    DWORD byte;
    while (true) {
        WaitForSingleObject(mut, INFINITE);
        cout << "Reading\n"; //this works
        ReadFile(mail, &a, sizeof(double), &byte, NULL);
        ReadFile(mail, &b, sizeof(double), &byte, NULL);
        cout << "I have read " << a << " " << b << endl;  //this message doesn't send
    }
    return 0;
}

更多参考:“Reading from a Mailslot”和“Writing to a Mailslot”的官方示例。

【讨论】:

  • 你的回答太棒了!但是现在互斥量不起作用:(我不能删除procces1和互斥量这是我大学的任务。我对c++的了解很差,我更喜欢另一种语言。
  • @Saliery 我添加了互斥锁,你可以试试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-23
  • 1970-01-01
相关资源
最近更新 更多