[英]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.