我整天都在c ++程序上工作,我找不到丢失的内容。问题是我尝试使用winapi与Mutex同步2个程序。我需要使用winapi文件映射将随机的内容从program1发送到program2,但是每次运行它时,program1都会在文件映射中写入所有内容,并且在运行每个实例之后,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释放的互斥锁可以再次由program1捕获。
每次我运行它时,program1都会写入文件映射中的所有内容,并且在运行每个实例之后,program2仅读取文件映射中写入的最后一个数字。
可能是program1发行版的互斥锁始终由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();
}
或者直接使用你用于同步的共享内存。使用的第一个字节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();
}
最后,正如您向我展示的那样,我使用了事件。非常感谢你!整个问题现在对我来说很清楚。