繁体   English   中英

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

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

我在 c++ 程序上工作了一整天,但我不知道缺少什么。 问题是我尝试使用 winapi 将 2 个程序与 Mutex 同步。 我需要使用 winapi 文件映射将随机内容从 program1 发送到 program2,但是每次我运行它时,program1 都会写入文件映射中的所有内容,并且在运行每个实例之后,program2 只会读取写入文件映射中的最后一个数字。 这两个之间没有同步。

我需要使用第一个程序中的 CreateProcess function 打开第二个 cpp 程序。 我认为我没有在正确的时间释放互斥锁,或者我没有在正确的时间启动第二个 cpp 文件,但我尝试的一切都没有奏效。

这是代码:

程序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;
}

程序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();
}

你能告诉我有什么问题吗?

您不能使用互斥锁来同步这两个进程。 program1 释放的互斥量可能会再次被program1 捕获。

每次我运行它时,program1 都会在文件映射中写入所有内容,并且在运行每个实例之后,program2 只会读取文件映射中写入的最后一个数字。

可能是program1释放的mutex一直被program1自己捕获(100次),然后被program2捕获。 一个进程需要通知另一个进程它已完成写入/读取(使用 IPC)。 您可以创建 2 个事件,然后使用它来通知每个进程中的另一个进程。

程序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;
}

程序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();
}

或者直接使用您正在使用的共享 memory 进行同步。 使用pdata的第一个字节作为信号位,每个进程监视是否轮到它执行。

程序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;
}

程序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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM