winapi — синхронный мультипроцесс с FileLock () для чтения / записи в одном и том же файле.

я собираюсь сделать 2 процесса, которые делают это:

Процесс А (клиент):
— Он открывает временный файл для записи (используйте GetTempFileName для
получить уникальное имя файла).
— Запускает процесс B, передавая в качестве аргумента имя файла.
— Он читает из стандартных строк ввода символов и пишет
эти строки в промежуточном файле.
Используйте строку постоянной длины (например, #define MAX_LEN 100).
— Останавливает чтение строк из стандартного ввода, когда он получает
конец файла (Ctrl-Z).
— Перед завершением пишет строку
«.end» — последняя строка файла.

Процесс B (сервер) работает следующим образом:
— Он открывает промежуточный файл для чтения.
— Он читает строки, как только они становятся доступными, и печатает их
на стандартный вывод.

  • Процесс A сохраняет файл открытым и всегда блокирует следующую часть
    файл перед разблокировкой предыдущей части.
  • Процесс B выполняется параллельно и читает общий файл, ожидая
    иметь доступ к отдельным строкам, чтобы прочитать их.

но кажется, что ReadFile в процессе B не ждет, пока fileLock будет удален, поэтому он завершится до того, как будет вставлена ​​первая строка

процесс А:

#include <windows.h>
#include <process.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <io.h>

#define MAX_LEN 100int _tmain(int argc, LPTSTR argv[]){TCHAR tmpFileName[MAX_PATH];
TCHAR tmppath[MAX_PATH];
TCHAR moment[MAX_PATH];
TCHAR command[MAX_PATH + 256];
UINT uRetVal = 0;
HANDLE bufferW,next;
DWORD n;
PROCESS_INFORMATION piS;
STARTUPINFO siS;
TCHAR buffer[MAX_LEN];
int i=0;OVERLAPPED ov = { 0, 0, 0, 0, NULL };
LARGE_INTEGER FilePos;ZeroMemory(&siS, sizeof(siS));
siS.cb = sizeof(siS);
ZeroMemory(&piS, sizeof(piS));
uRetVal = GetTempFileName(_T("."), // directory for tmp files
_T(""),     // temp file name prefix
0,                // create unique name
tmpFileName);  // buffer for name

if (uRetVal == 0)
{
_tprintf("\n errore apertura temp file");
return (3);
}GetCurrentDirectory(MAX_PATH, moment);
//_stprintf(tmppath, "%s\\ %s",moment,tmpFileName);
_tprintf("\n CLIENT PATH %s  \n",moment);//_stprintf(command,"%s %s","C:\\Users\\zio gianni\\Documents\\Visual Studio 2013\\Projects\\lab11server\\Debug\\lab11server.exe",tmpFileName);
_stprintf(command, "%s %s", "server.exe", tmpFileName);
bufferW = CreateFile(tmpFileName, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
next = CreateFile(tmpFileName, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (next == INVALID_HANDLE_VALUE) {

_tprintf(_T("Cannot open client file. Error: %x\n"),
GetLastError());
_tprintf(" \n Nome File: %s\n", "./prova.bin");
return 2;
}
if (bufferW == INVALID_HANDLE_VALUE) {

_tprintf(_T("Cannot open client file. Error: %x\n"),
GetLastError());
_tprintf(" \n Nome File: %s\n", "./prova.bin");
return 2;
}FilePos.QuadPart = i*MAX_LEN * sizeof (TCHAR);
ov.Offset = FilePos.LowPart;
ov.OffsetHigh = FilePos.HighPart;
ov.hEvent = 0;LockFileEx(bufferW, LOCKFILE_EXCLUSIVE_LOCK, 0, FilePos.LowPart, FilePos.HighPart, &ov);
printf("file bloccato avvio server con comand: %s\n", command);if (!CreateProcess(NULL,   // No module name (use command line)
command,        // Command line
NULL,           // Process handle not inheritable
NULL,           // Thread handle not inheritable
TRUE,          // Set handle inheritance to FALSE
0,              // No creation flags
NULL,           // Use parent's environment block
NULL,           // Use parent's starting directory
&siS,            // Pointer to STARTUPINFO structure
&piS)           // Pointer to PROCESS_INFORMATION structure
)
{
printf("CreateProcess failed (%d).\n", GetLastError());
return -5;
}while (TRUE){scanf("%s",buffer);
if (strcmp(buffer, "EOF")==0){

break;
}

WriteFile(bufferW, buffer, MAX_LEN*sizeof(TCHAR), &n, NULL);FilePos.QuadPart =(i+1)* MAX_LEN * sizeof (TCHAR);
ov.Offset = FilePos.LowPart;
ov.OffsetHigh = FilePos.HighPart;
ov.hEvent = 0;

if (i % 2 == 0){

LockFile(next, LOCKFILE_EXCLUSIVE_LOCK, 0, FilePos.LowPart, FilePos.HighPart, &ov);
FilePos.QuadPart = (i )* MAX_LEN * sizeof (TCHAR);
ov.Offset = FilePos.LowPart;
ov.OffsetHigh = FilePos.HighPart;
ov.hEvent = 0;
UnlockFile(bufferW, 0, 0, 0, &ov);
}
else{

LockFile(bufferW, LOCKFILE_EXCLUSIVE_LOCK, 0, FilePos.LowPart, FilePos.HighPart, &ov);
FilePos.QuadPart = (i )* MAX_LEN * sizeof (TCHAR);
ov.Offset = FilePos.LowPart;
ov.OffsetHigh = FilePos.HighPart;
ov.hEvent = 0;
UnlockFile(next, 0, 0, 0, &ov);
}

i++;
}sprintf(buffer, ".end");

WriteFile(bufferW, buffer, MAX_LEN*sizeof(TCHAR), &n ,NULL);if (i % 2 == 0){FilePos.QuadPart = (i)* MAX_LEN * sizeof (TCHAR);
ov.Offset = FilePos.LowPart;
ov.OffsetHigh = FilePos.HighPart;
ov.hEvent = 0;
UnlockFile(bufferW, 0, FilePos.LowPart, FilePos.HighPart, &ov);
}
else{FilePos.QuadPart = (i)* MAX_LEN * sizeof (TCHAR);
ov.Offset = FilePos.LowPart;
ov.OffsetHigh = FilePos.HighPart;
ov.hEvent = 0;
UnlockFile(next, 0, FilePos.LowPart, FilePos.HighPart, &ov);
}

// Wait until child process exits.
WaitForSingleObject(piS.hProcess, INFINITE);

// Close process and thread handles.
CloseHandle(piS.hProcess);
CloseHandle(piS.hThread);return 0;
}

процесс Б:

#include <windows.h>
#include <process.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <io.h>

#define MAX_LEN 100int _tmain(int argc, LPTSTR argv[]){

HANDLE read;
DWORD n;
int i = 0;
TCHAR buffer[MAX_LEN], path[MAX_LEN];
OVERLAPPED ov = { 0, 0, 0, 0, NULL };
LARGE_INTEGER FilePos;

read = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (read == INVALID_HANDLE_VALUE) {

_tprintf(_T("Cannot open input file. Error: %x\n"),
GetLastError());
_tprintf(" \n Nome File: %s\n", argv[1]);
return 2;
}
_tprintf(" \n Nome File APERTO: %s\n", argv[1]);

GetCurrentDirectory(MAX_LEN,path);
_tprintf(" \n path server: %s\n%s\n", path,argv[1]);while (ReadFile(read, buffer, MAX_LEN*sizeof(TCHAR), &n, &ov) && n>0 ){if (n == 0){
fprintf(stderr,"error readfle\n");
return -5;
}
if (strncmp(buffer, ".end", 4) == 0){
_tprintf(" \n STAMPA SERVER: esco\n");
break;
}

_tprintf(" \n STAMPA SERVER: %s\n", buffer);}if (n == 0){
fprintf(stderr, "error readfle\n");
return -5;
}
_tprintf("\n END SERVER");
return 0;
}

1

Решение

Не используйте актуальные файлы для межпроцессного взаимодействия. Используйте именованные каналы!

Ищи CreateNamedPipe, Есть много примеров.

2

Другие решения


По вопросам рекламы [email protected]