我正在训练做这两个过程:
进程A(客户端):-它打开一个临时文件用于写入(使用GetTempFileName来获取唯一的文件名)。-它启动进程B,传递文件的名称作为参数。-它从标准输入字符串中读取字符,并写入中间文件中的那些字符串。使用固定长度的字符串(例如,#define MAX_LEN 100)。-当它接收到字符串时停止从标准输入读取字符串文件尾(ctrl - z)。-在结束之前,写入字符串"指标"最终作为文件的最后一行。进程B(服务器)的工作方式如下:-打开中间文件进行读取。-只要行可用,它就读取行,并打印它们标准输出。
- 进程A保持文件打开,并且它总是锁定下一部分
- 进程B并行运行,它读取一个共享文件,等待可以访问单行读取它们。
但是进程B上的ReadFile没有等到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 100
int _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: %xn"),
GetLastError());
_tprintf(" n Nome File: %sn", "./prova.bin");
return 2;
}
if (bufferW == INVALID_HANDLE_VALUE) {
_tprintf(_T("Cannot open client file. Error: %xn"),
GetLastError());
_tprintf(" n Nome File: %sn", "./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: %sn", 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;
}
进程B :
#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 100
int _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: %xn"),
GetLastError());
_tprintf(" n Nome File: %sn", argv[1]);
return 2;
}
_tprintf(" n Nome File APERTO: %sn", argv[1]);
GetCurrentDirectory(MAX_LEN,path);
_tprintf(" n path server: %sn%sn", path,argv[1]);
while (ReadFile(read, buffer, MAX_LEN*sizeof(TCHAR), &n, &ov) && n>0 ){
if (n == 0){
fprintf(stderr,"error readflen");
return -5;
}
if (strncmp(buffer, ".end", 4) == 0){
_tprintf(" n STAMPA SERVER: escon");
break;
}
_tprintf(" n STAMPA SERVER: %sn", buffer);
}
if (n == 0){
fprintf(stderr, "error readflen");
return -5;
}
_tprintf("n END SERVER");
return 0;
}
不要使用实际文件进行进程间通信。使用命名管道!
搜索CreateNamedPipe
,有很多例子