多进程通信
进程与进程在运行期间,需要数据的交换即进程通信 。进程间通信方式:
共享内存
管道(pipe )
信号量
消息队列:MFC中SendMessage()
文件
端口
共享内存
TCHAR szName[] = TEXT("Global\\MyFileMappingObject");//命名共享内存
hMapFile = CreateFileMapping(szName..);//创建共享内存
pBuf = (LPTSTR)MapViewOfFile(hMapFile..);//分配内存
Read/Write
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
发送端
#include<Windows.h>
#include<string.h>
#include<stdio.h>
#define BUF_SIZE 1024
TCHAR szName[] = TEXT("Global\\MappingObject");
int main(int argc, char* argv[]) {
HANDLE MapFile;
LPCSTR pBuf;
MapFile = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
BUF_SIZE,
szName);
if (MapFile == NULL) {
printf("FALSE");
CloseHandle(MapFile);
return 1;
}
pBuf = (LPTSTR)MapViewOfFile(MapFile,
FILE_MAP_ALL_ACCESS,
0,
0,
BUF_SIZE);
if (pBuf == NULL) {
printf("FALSE");
CloseHandle(MapFile);
return 1;
}
//往里面写
while (1) {
TCHAR s[BUF_SIZE];
printf("input\n");
gets_s(s, BUF_SIZE);
memcpy((PVOID)pBuf, s, BUF_SIZE);
}
UnmapViewOfFile(pBuf);
CloseHandle(MapFile);
return 0;
}
接收端
#include<stdio.h>
#include<Windows.h>
#include<string.h>
#define BUF_SIZE 1024
TCHAR szName[] = TEXT("Global\\MappingObject");
int main(int argc, char* argv[]) {
HANDLE MapFile;
LPCSTR pBuf;
MapFile = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
BUF_SIZE,
szName);
if (MapFile == NULL) {
printf("FALSE");
return 1;
}
pBuf = (LPTSTR)MapViewOfFile(MapFile,
FILE_MAP_ALL_ACCESS,
0,
0,
BUF_SIZE);
if (pBuf == NULL) {
printf("FALSE");
CloseHandle(MapFile);
return 1;
}
//读共享内存中的数据
while (1) {
printf("get:%s\n", pBuf);
getchar();
}
UnmapViewOfFile(pBuf);
CloseHandle(MapFile);
return 0;
}
命名管道
管道是基于文件描述符的通信方式,一个进程向管道中写的内容被管道另一端的进程读出,写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区头部读出数据,两个进程即可以读也可以写,是双向的
#define PIPE_NAME "\\\\.\\Pipe\\test"//转义字符
CreateNamedPipe()
ConnectNamedPipe()
WriteFile()
ReadFile()
客户端
#include<stdio.h>
#include<Windows.h>
#define PIPE_NAME L"\\\\.\\Pipe\\test"
HANDLE hPipe = INVALID_HANDLE_VALUE;
int main()
{
char buffer[1024];
DWORD Write;
DWORD Read;
printf("server\n");
hPipe = CreateNamedPipe(PIPE_NAME,//管道名
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
1,//支持多少个示例
0,
0,
1000,//超时的间隔
NULL);//服务端打开管道
if (hPipe == INVALID_HANDLE_VALUE) {
printf("FALSE");
return 0;
}
printf("Wait\n");
if (ConnectNamedPipe(hPipe, NULL) == FALSE) {
printf("Connect FALSE");
return 0;
}
printf("Connect\n");
while (1) {
scanf_s("%s", buffer, 1024);
if (WriteFile(hPipe, buffer, (DWORD)strlen(buffer), &Write, NULL) == 0) {
printf("Write False\n");
break;
}
if (ReadFile(hPipe, buffer, sizeof(buffer), &Read, NULL)==0) {
break;
}
printf("read:%s\n", buffer);
}
printf("Pipe closed");
return 0;
}
服务端
#include<stdio.h>
#include<Windows.h>
#define PIPE_NAME L"\\\\.\\Pipe\\test"
HANDLE hPipe = INVALID_HANDLE_VALUE;
int main() {
char buffer[1024];
DWORD Read;
DWORD Write;
printf("test\n");
hPipe = CreateFile(PIPE_NAME,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);//创建管道
if (hPipe == INVALID_HANDLE_VALUE)
{
printf("FALSE");
return 0;
}
printf("Connect\n");
while (1) {
if (ReadFile(hPipe, buffer, sizeof(buffer), &Read,NULL)==0){
break;
}
buffer[Read] = 0;
printf("%s\n", buffer);
if (WriteFile(hPipe, buffer, (DWORD)strlen(buffer), &Write, NULL)== 0) {
printf("Write Failed");
break;
}
}
printf("Pipe closed");
return 0;
}
客户端创建管道,服务端打开管道。