[英]Should programs check for failure on WinAPI functions that “shouldn't”, but can, fail?
[英]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.