简体   繁体   English

ReleaseMutex 在错误的时间和程序不同步 winapi

[英]ReleaseMutex at the wrong time and the programs don't synchronize winapi

I have worked the entire day on a c++ program and I can't find out what's missing.我在 c++ 程序上工作了一整天,但我不知道缺少什么。 The problem is that I try to synchronize 2 programs with Mutex using winapi.问题是我尝试使用 winapi 将 2 个程序与 Mutex 同步。 I need to send random things from program1 to program2 using winapi file mapping but everytime I run it program1 writes in file mapping everything and after it runs every instance, program2 reads only the last number wrote in file mapping.我需要使用 winapi 文件映射将随机内容从 program1 发送到 program2,但是每次我运行它时,program1 都会写入文件映射中的所有内容,并且在运行每个实例之后,program2 只会读取写入文件映射中的最后一个数字。 There is no synchronize between these 2.这两个之间没有同步。

I need to open the second cpp program with CreateProcess function from the first program.我需要使用第一个程序中的 CreateProcess function 打开第二个 cpp 程序。 I think that I don't release the mutex at the right time or I didn't start the second cpp file at the right time but everything I tried didn't work.我认为我没有在正确的时间释放互斥锁,或者我没有在正确的时间启动第二个 cpp 文件,但我尝试的一切都没有奏效。

Here is the code:这是代码:

Program1:程序1:

#include <iostream>
#include <Windows.h>
#include <time.h>
using namespace std;

struct RandomSum {
   DWORD a;
   DWORD b;
};


int main()
{
   //srand((unsigned int)time(NULL));
   cout << "inside process 1" << endl;

   HANDLE common_mutex = CreateMutex(
       NULL,              // default security attributes
       TRUE,             // initially not owned
       "mainMutex");             // unnamed mutex


   HANDLE create_file_mapping_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 
  0, 1024 * 1024, "data");
   if (create_file_mapping_handle == NULL) {
       printf("Cannot create file mapping. Error code: %d", GetLastError());
       return 0;
   }

   unsigned char* pData = (unsigned char*)MapViewOfFile(create_file_mapping_handle, 
   FILE_MAP_ALL_ACCESS, 0, 0, 0);
   if (pData == NULL) {
       printf("Cannot get pointer to file mapping. Error code: %d", GetLastError());
       CloseHandle(create_file_mapping_handle);
       return 0;
   }



   //create new process
   PROCESS_INFORMATION process2;
   STARTUPINFO si;
   memset(&si, 0, sizeof(si));
   si.cb = sizeof(si);
   if (!CreateProcess("C:\\Users\\raztu\\Desktop\\tema5to6CSSO\\process1\\Debug\\process2.exe", NULL, 
NULL, NULL, FALSE, 0, NULL, NULL, &si, &process2)) {
       printf("Cannot create process.\n");
       return 0;
   }


   for (int i = 0; i < 50; ++i) {

   }

   int counter = 0;
   while (counter < 100) {
       DWORD dwWaitResult = WaitForSingleObject(
           common_mutex,    // handle to mutex
           INFINITE);  // no time-out interval

       if (dwWaitResult == WAIT_OBJECT_0) {
           cout << "am intrat in sender process si scriu in file mapping" << endl;
           RandomSum test;

           DWORD randomNumber = rand() % 50;
           test.a = randomNumber;
           test.b = 2 * test.a;
           memcpy(pData, &test, sizeof(RandomSum));
           cout << "in process 1: " << "a = " << test.a << " b= " << test.b << endl;
        
       }
       ReleaseMutex(common_mutex);
       cout << "last cout" << endl;
       ++counter;
   }

   CloseHandle(create_file_mapping_handle);
   CloseHandle(common_mutex);
   //getchar();
   return 0;
}

Program2:程序2:

#include <iostream>
#include <Windows.h>
#include <time.h>
using namespace std;

struct RandomSum {
   DWORD a;
   DWORD b;
};

int main()
{
   cout << "inside process2" << endl;
   //srand((unsigned int)time(NULL));



cout << "something new in process2" << endl;


LPCWSTR data = L"data";
HANDLE hData = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "data");

unsigned char* pData = (unsigned char*)MapViewOfFile(hData, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (pData == NULL) {
    printf("Cannot get pointer to file mapping. Error code: %d", GetLastError());
    CloseHandle(hData);
    return 0;
}

HANDLE common_mutex = OpenMutex(
    SYNCHRONIZE,
    FALSE,
    "mainMutex"
);

int counter = 0;
while (counter < 100) {
    DWORD dwWaitResult = WaitForSingleObject(
        common_mutex,    // handle to mutex
        INFINITE);  // no time-out interval

    if (dwWaitResult == WAIT_OBJECT_0) {
        cout << "a inceput procesul 2" << endl;
        RandomSum test;

        memcpy(&test, pData, sizeof(RandomSum));

        cout << "a is" << test.a << " and b is " << test.b << endl;
        
    }
    ReleaseMutex(common_mutex);
    ++counter;
   
}



CloseHandle(hData);
CloseHandle(common_mutex);
//getchar();
}

Could you tell me what's wrong?你能告诉我有什么问题吗?

You cannot use mutex to synchronize these two processes.您不能使用互斥锁来同步这两个进程。 The mutex released by program1 may be captured by program1 again. program1 释放的互斥量可能会再次被program1 捕获。

everytime I run it program1 writes in file mapping everything and after it runs every instance, program2 reads only the last number wrote in file mapping.每次我运行它时,program1 都会在文件映射中写入所有内容,并且在运行每个实例之后,program2 只会读取文件映射中写入的最后一个数字。

It may be that the mutex of program1 release was always captured by program1 itself(100 times), and then captured by program2.可能是program1释放的mutex一直被program1自己捕获(100次),然后被program2捕获。 One process need to notify the other process that it has finished writing/reading(with IPC).一个进程需要通知另一个进程它已完成写入/读取(使用 IPC)。 You can create 2 events and then use it to notify the other process in each process.您可以创建 2 个事件,然后使用它来通知每个进程中的另一个进程。

Program1:程序1:

#include <iostream>
#include <Windows.h>
#include <time.h>
using namespace std;

struct RandomSum {
    DWORD a;
    DWORD b;
};


int main()
{
    //srand((unsigned int)time(NULL));
    cout << "inside process 1" << endl;

    HANDLE hEvent1 = CreateEvent(NULL, FALSE, TRUE, "MyEvent1");
    HANDLE hEvent2 = CreateEvent(NULL, FALSE, FALSE, "MyEvent2");

    HANDLE create_file_mapping_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
        0, 1024 * 1024, "data");
    if (create_file_mapping_handle == NULL) {
        printf("Cannot create file mapping. Error code: %d", GetLastError());
        return 0;
    }

    unsigned char* pData = (unsigned char*)MapViewOfFile(create_file_mapping_handle,
        FILE_MAP_ALL_ACCESS, 0, 0, 0);
    if (pData == NULL) {
        printf("Cannot get pointer to file mapping. Error code: %d", GetLastError());
        CloseHandle(create_file_mapping_handle);
        return 0;
    }

    //create new process
    PROCESS_INFORMATION process2;
    STARTUPINFO si;
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    if (!CreateProcess("C:\\path\\program2.exe", NULL,
        NULL, NULL, FALSE, 0, NULL, NULL, &si, &process2)) {
        printf("Cannot create process.\n");
        return 0;
    }
    CloseHandle(process2.hThread);
    CloseHandle(process2.hProcess);    
    int counter = 0;
    while (counter < 100) {
        DWORD dwWaitResult = WaitForSingleObject(
            hEvent1,    // handle to mutex
            INFINITE);  // no time-out interval

        if (dwWaitResult == WAIT_OBJECT_0) {
            cout << "am intrat in sender process si scriu in file mapping" << endl;
            RandomSum test;

            DWORD randomNumber = rand() % 50;
            test.a = randomNumber;
            test.b = 2 * test.a;
            memcpy(pData, &test, sizeof(RandomSum));
            cout << "in process 1: " << "a = " << test.a << " b= " << test.b << endl;
            cout << "last cout" << endl;
            SetEvent(hEvent2);
        }

        ++counter;
    }
    UnmapViewOfFile(pData);
    CloseHandle(create_file_mapping_handle);
    CloseHandle(hEvent1);
    CloseHandle(hEvent2);
    //getchar();
    return 0;
}

Program2:程序2:

#include <iostream>
#include <Windows.h>
#include <time.h>
using namespace std;

struct RandomSum {
    DWORD a;
    DWORD b;
};

int main()
{
    cout << "inside process2" << endl;
    //srand((unsigned int)time(NULL));

    cout << "something new in process2" << endl;
    HANDLE hEvent1 = OpenEvent(EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, "MyEvent1");
    HANDLE hEvent2 = OpenEvent(EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, "MyEvent2");

    LPCWSTR data = L"data";
    HANDLE hData = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "data");

    unsigned char* pData = (unsigned char*)MapViewOfFile(hData, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    if (pData == NULL) {
        printf("Cannot get pointer to file mapping. Error code: %d", GetLastError());
        CloseHandle(hData);
        return 0;
    }

    int counter = 0;
    while (counter < 100) {
        DWORD dwWaitResult = WaitForSingleObject(
            hEvent2,    // handle to mutex
            INFINITE);  // no time-out interval
        if (dwWaitResult == WAIT_OBJECT_0) {
            cout << "a inceput procesul 2" << endl;
            RandomSum test;

            memcpy(&test, pData, sizeof(RandomSum));

            cout << "a is " << test.a << " and b is " << test.b << endl;
            SetEvent(hEvent1);
        }
        ++counter;

    }
    UnmapViewOfFile(pData);
    CloseHandle(hData);
    CloseHandle(hEvent1);
    CloseHandle(hEvent2);
    //getchar();
}

Or directly use the shared memory you are using for synchronization.或者直接使用您正在使用的共享 memory 进行同步。 Use the first byte of pdata as a signal bit, and each process monitors whether it is its turn to execute.使用pdata的第一个字节作为信号位,每个进程监视是否轮到它执行。

Program1:程序1:

#include <iostream>
#include <Windows.h>
#include <time.h>
using namespace std;

struct RandomSum {
    DWORD a;
    DWORD b;
};
BOOL WaitForProcess2(unsigned char* shared_address)
{
    while (*shared_address != 1);//wait until the process1 set the first byte to 1;
    return true;
}

int main()
{
    //srand((unsigned int)time(NULL));
    cout << "inside process 1" << endl;


    HANDLE create_file_mapping_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
        0, 1024 * 1024, "data");
    if (create_file_mapping_handle == NULL) {
        printf("Cannot create file mapping. Error code: %d", GetLastError());
        return 0;
    }

    unsigned char* pData = (unsigned char*)MapViewOfFile(create_file_mapping_handle,
        FILE_MAP_ALL_ACCESS, 0, 0, 0);
    if (pData == NULL) {
        printf("Cannot get pointer to file mapping. Error code: %d", GetLastError());
        CloseHandle(create_file_mapping_handle);
        return 0;
    }
    *pData = 1;
    //create new process
    PROCESS_INFORMATION process2;
    STARTUPINFO si;
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    if (!CreateProcess("C:\\path\\program2.exe", NULL,
        NULL, NULL, FALSE, 0, NULL, NULL, &si, &process2)) {
        printf("Cannot create process.\n");
        return 0;
    }
    CloseHandle(process2.hThread);
    CloseHandle(process2.hProcess);
    int counter = 0;
    while (counter < 100) {
        if (WaitForProcess2(pData)) {
            cout << "am intrat in sender process si scriu in file mapping" << endl;
            RandomSum test;

            DWORD randomNumber = rand() % 50;
            test.a = randomNumber;
            test.b = 2 * test.a;
            memcpy(pData+1, &test, sizeof(RandomSum)); //"pData + 1" skip the first signal bit
            cout << "in process 1: " << "a = " << test.a << " b= " << test.b << endl;
            cout << "last cout" << endl;
            *pData = 2;
        }
        ++counter;
    }
    UnmapViewOfFile(pData);
    CloseHandle(create_file_mapping_handle);
    //getchar();
    return 0;
}

Program2:程序2:

#include <iostream>
#include <Windows.h>
#include <time.h>
using namespace std;

struct RandomSum {
    DWORD a;
    DWORD b;
};
BOOL WaitForProcess1(unsigned char* shared_address)
{
    while (*shared_address != 2); //wait until the process1 set the first byte to 2;
    return true;
}
int main()
{
    cout << "inside process2" << endl;
    //srand((unsigned int)time(NULL));

    cout << "something new in process2" << endl;

    LPCWSTR data = L"data";
    HANDLE hData = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "data");

    unsigned char* pData = (unsigned char*)MapViewOfFile(hData, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    if (pData == NULL) {
        printf("Cannot get pointer to file mapping. Error code: %d", GetLastError());
        CloseHandle(hData);
        return 0;
    }

    int counter = 0;
    while (counter < 100) {

        if (WaitForProcess1(pData)) {
            cout << "a inceput procesul 2" << endl;
            RandomSum test;

            memcpy(&test, pData + 1, sizeof(RandomSum)); //"pData + 1" skip the first signal bit

            cout << "a is " << test.a << " and b is " << test.b << endl;
            *pData = 1;
        }
        ++counter;

    }
    UnmapViewOfFile(pData);
    CloseHandle(hData);

    //getchar();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 程序是否应检查“不应该”的WinAPI函数是否失败,但可能会失败? - Should programs check for failure on WinAPI functions that “shouldn't”, but can, fail? WinAPI 如果我不翻译和发送未处理的消息会发生什么 - WinAPI What happens if I don't Translate and Dispatch unhandled message 如何同步两个程序的计时器 - How to synchronize timers of two programs WinAPI和启动位置中的程序被用户禁用 - WinAPI and programs in startup locations disabled by user 使用C ++以编程方式修复Windows中的程序-也许可以通过WinAPI修复吗? - Repair programs in Windows programatically in C++ - maybe somehow by WinAPI? 默认情况下如何包含某些头文件,这样我就不必在每个程序中输入它们 - how to include certain header files by default so that i don't have to type them in every programs 从QtCreator启动时,以“简单c ++”模式编译的程序不起作用 - Programs compiled in “simple c++” mode don't work when launching them from QtCreator 想做一个static的库给其他程序使用,不知道为什么失败了 - I want to make a static library for other programs to use, but I don't know why it failed winapi 不响应按键 - winapi doesn't respond to keypress 使用WinAPI无法显示窗口 - Can't display window with WinAPI
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM