ReleaseMutex 在错误的时间和程序不同步 winapi
ReleaseMutex at the wrong time and the programs don't synchronize winapi
我在一个 C++ 程序上工作了一整天,但我找不到缺少的东西。
问题是我尝试使用 winapi 将 2 个程序与 Mutex 同步。我需要使用 winapi 文件映射将随机的东西从 program1 发送到 program2 但每次我 运行 它 program1 写入文件映射所有内容并且在它之后 运行s 每个实例,program2 只读取文件中写入的最后一个数字映射。这两个之间没有同步。
我需要用第一个程序的 CreateProcess 函数打开第二个 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释放的mutex可能会再次被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释放的mutex一直是program1自己捕获的(100次),然后被program2捕获。
一个进程需要通知另一个进程它已经完成 writing/reading(使用 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();
}
或者直接使用你正在使用的共享内存进行同步。用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();
}
我在一个 C++ 程序上工作了一整天,但我找不到缺少的东西。 问题是我尝试使用 winapi 将 2 个程序与 Mutex 同步。我需要使用 winapi 文件映射将随机的东西从 program1 发送到 program2 但每次我 运行 它 program1 写入文件映射所有内容并且在它之后 运行s 每个实例,program2 只读取文件中写入的最后一个数字映射。这两个之间没有同步。
我需要用第一个程序的 CreateProcess 函数打开第二个 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释放的mutex可能会再次被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释放的mutex一直是program1自己捕获的(100次),然后被program2捕获。 一个进程需要通知另一个进程它已经完成 writing/reading(使用 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();
}
或者直接使用你正在使用的共享内存进行同步。用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();
}