windows C++进程间和线程间通信


Thank Swarajya Pendharkar and MSDN very much

进程间通信

进程基本概念

In computer science, inter-process communication or interprocess communication (IPC) refers specifically to the mechanisms an operating system provides to allow processes it manages to share data. Typically, applications can use IPC categorized as clients and servers, where the client requests data and the server responds to client requests.Many applications are both clients and servers, as commonly seen in distributed computing. Methods for achieving IPC are divided into categories which vary based on software requirements, such as performance and modularity requirements, and system circumstances, such as network bandwidth and latency.

Approaches

Method Short Description Provided by (operating systems or other environments)
File A record stored on disk, or a record synthesized on demand by a file server, which can be accessed by multiple processes. Most operating systems
Signal; also Asynchronous System Trap A system message sent from one process to another, not usually used to transfer data but instead used to remotely command the partnered process. Most operating systems
Socket A data stream sent over a network interface, either to a different process on the same computer or to another computer on the network. Typically byte-oriented, sockets rarely preserve message boundaries. Data written through a socket requires formatting to preserve message boundaries. Most operating systems
Message queue A data stream similar to a socket, but which usually preserves message boundaries. Typically implemented by the operating system, they allow multiple processes to read and write to the message queue without being directly connected to each other. Most operating systems
Pipe A unidirectional data channel. Data written to the write end of the pipe is buffered by the operating system until it is read from the read end of the pipe. Two-way data streams between processes can be achieved by creating two pipes utilizing standard input and output. All POSIX systems, Windows
Named pipe A pipe implemented through a file on the file system instead of standard input and output. Multiple processes can read and write to the file as a buffer for IPC data. All POSIX systems, Windows, AmigaOS 2.0+
Semaphore A simple structure that synchronizes multiple processes acting on shared resources. All POSIX systems, Windows, AmigaOS
Shared memory Multiple processes are given access to the same block of memory which creates a shared buffer for the processes to communicate with each other. All POSIX systems, Windows
Message passing Allows multiple programs to communicate using message queues and/or non-OS managed channels, commonly used in concurrency models. Used in RPC, RMI, and MPI paradigms, Java RMI, CORBA, DDS, MSMQ, MailSlots, QNX, others
Memory-mapped file A file mapped to RAM and can be modified by changing memory addresses directly instead of outputting to a stream. This shares the same benefits as a standard file. All POSIX systems, Windows

进程间通信(IPC)实现

The following IPC mechanisms are supported by Windows:

  • Clipboard
  • COM
  • Data Copy
  • DDE
  • File Mapping
  • Mailslots
  • Pipes
  • RPC
  • Windows Sockets

进程间通信之共享内存实现

File mapping enables a process to treat the contents of a file as if they were a block of memory in the process’s address space. The process can use simple pointer operations to examine and modify the contents of the file. When two or more processes access the same file mapping, each process receives a pointer to memory in its own address space that it can use to read or modify the contents of the file. The processes must use a synchronization object, such as a semaphore, to prevent data corruption in a multitasking environment.


Following are some of the Win32 APIs that are used when working with shared memory (memory mapped objects):

  • CreateFileMapping()
  • MapViewOfFile()
  • UnMapViewOfFile()
  • CloseHandle()

Key Point: Mailslots offer an easy way for applications to send and receive short messages. They also provide the ability to broadcast messages across all computers in a network domain.


#include <iostream>
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>

using namespace std;
//-------------------------------
#define MAX_SH_MEM_SIZE             1024
#define MAX_READ_PROCESSES_ALLOWED  3
#define WAIT_TIME_OUT               100
//-------------------------------

//-------------------------------
/*
Global variables
*/


HANDLE  g_hReadEvent[MAX_READ_PROCESSES_ALLOWED];
TCHAR   g_szReadEventName[] = _T("My Read Event");

HANDLE  g_hWriteEvent = NULL;
TCHAR   g_szWriteEventName[] = _T("My Write Event");

HANDLE  g_hSharedMemory = NULL;
LPTSTR  g_pBuffer = NULL;
TCHAR   g_szSharedMemoryName[] = _T("My Shared Memory");

bool    Initialize();
void    DeInitialize();
void    DisplayOptions();
bool    RecvAndProcessOption();
void    WriteAndPrint();
void    ReadAndPrint();

int main(int argv, char* argc[], char* env[]){
    if (Initialize()){
        std::cout << "Initialization of process was successful" << endl;
    }
    else
    {
        DeInitialize();
        std::cout << "Initialization of the process was not successful" << endl;
        return 1;
    }

    bool bContinue = true;
    while (bContinue){
        DisplayOptions();
        bContinue = RecvAndProcessOption();
    }
    DeInitialize();
}

bool    Initialize(){
    for (int i = 0; i < MAX_READ_PROCESSES_ALLOWED; i++)
    {
        g_hReadEvent[i] = NULL;
    }
    TCHAR szBuffer[32];
    /*
    原型
    int sprintf( char *buffer, const char *format, [ argument] … );
    参数列表
    buffer:char型指针,指向将要写入的字符串的缓冲区。
    format:格式化字符串。
    [argument]...:可选参数,可以是任何类型的数据。
    返回值
    返回写入buffer 的字符数,出错则返回-1. 如果 buffer 或 format 是空指针,且不出错而继续,函数将返回-1,并且 errno 会被设置为 EINVAL。
    sprintf 返回被写入buffer 的字节数,结束字符‘\0’不计入内。即,如果“Hello”被写入空间足够大的buffer后,函数sprintf 返回5。
    */
    for (int i = 0; i < MAX_READ_PROCESSES_ALLOWED; i++)
    {
        _stprintf_s(szBuffer, _T("%s %d"), g_szReadEventName, i);
        g_hReadEvent[i] = CreateEvent(NULL, false, true, szBuffer);
        if (NULL == g_hReadEvent[i]){
            return false;
        }
    }
    /*
    HANDLE CreateEvent(
    LPSECURITY_ATTRIBUTESlpEventAttributes,// 安全属性
    BOOLbManualReset,// 复位方式
    BOOLbInitialState,// 初始状态
    LPCTSTRlpName // 对象名称 事件对象的名称
    );

    如果函数调用成功,函数返回事件对象的句柄。如果对于命名的对象,在函数调用前已经被创建,函数将返回存在的事件对象的句柄,而且在GetLastError函数中返回ERROR_ALREADY_EXISTS。
    如果函数失败,函数返回值为NULL,如果需要获得详细的错误信息,需要调用GetLastError。
    */
    g_hWriteEvent = CreateEvent(NULL, false, true, g_szWriteEventName);
    if (NULL == g_hWriteEvent){
        return false;
    }
    /*函数原型
    HANDLE WINAPI CreateFileMapping(
    _In_HANDLE hFile,
    _In_opt_LPSECURITY_ATTRIBUTES lpAttributes,
    _In_DWORD flProtect,
    _In_DWORD dwMaximumSizeHigh,
    _In_DWORD dwMaximumSizeLow,
    _In_opt_LPCTSTR lpName);
    创建一个新的文件映射内核对象。
    */
    g_hSharedMemory = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MAX_SH_MEM_SIZE, g_szSharedMemoryName);
    if (NULL == g_hSharedMemory || INVALID_HANDLE_VALUE == g_hSharedMemory){
        std::cout << "Error occured while creating file mapping object:" << GetLastError() << endl;
        return false;
    }
    /*
    函数原型
    LPVOID WINAPI MapViewOfFile(
    __in HANDLE hFileMappingObject,
    __in DWORD dwDesiredAccess,
    __in DWORD dwFileOffsetHigh,
    __in DWORD dwFileOffsetLow,
    __in SIZE_T dwNumberOfBytesToMap
    );
    MapViewOfFile,计算机语言。将一个文件映射对象映射到当前应用程序的地址空间。MapViewOfFileEx允许我们指定一个基本地址来进行映射。
    参数1:hFileMappingObject 为CreateFileMapping()返回的文件映像对象句柄。
    参数2:dwDesiredAccess 映射对象的文件数据的访问方式,而且同样要与CreateFileMapping()函数所设置的保护属性相匹配。 可取以下值:
    FILE_MAP_ALL_ACCESS 等价于CreateFileMapping的 FILE_MAP_WRITE|FILE_MAP_READ. 文件映射对象被创建时必须指定PAGE_READWRITE 选项.
    FILE_MAP_COPYA 可以读取和写入文件.写入操作会导致系统为该页面创建一份副本.在调用CreateFileMapping时必须传入PAGE_WRITECOPY保护属性.
    FILE_MAP_EXECUTE 可以将文件中的数据作为代码来执行.在调用CreateFileMapping时可以传入PAGE_EXECUTE_READWRITE或PAGE_EXECUTE_READ保护属性.
    FILE_MAP_READ 可以读取文件.在调用CreateFileMapping时可以传入PAGE_READONLY或PAGE_READWRITE保护属性.
    FILE_MAP_WRITEA 可以读取和写入文件.在调用CreateFileMapping时必须传入PAGE_READWRITE保护属性.
    参数3:dwFileOffsetHigh 表示文件映射起始偏移的高32位.
    参数4:dwFileOffsetLow 表示文件映射起始偏移的低32位.(64KB对齐不是必须的)
    参数5:dwNumberOfBytes 指定映射文件的字节数.

    */
    g_pBuffer = (LPTSTR)MapViewOfFile(g_hSharedMemory, FILE_MAP_ALL_ACCESS, 0, 0, MAX_SH_MEM_SIZE);
    if (NULL == g_pBuffer){
        std::cout << "Error occured while mapping view of the file:" << GetLastError() << endl;
        return false;
    }
    return true;
}


void    DeInitialize(){
    for (int i = 0; i < MAX_READ_PROCESSES_ALLOWED; i++)
    {
        CloseHandle(g_hReadEvent[i]);
    }
    CloseHandle(g_hWriteEvent);
    UnmapViewOfFile(g_pBuffer);
    CloseHandle(g_hSharedMemory);
}

void DisplayOptions(){
    cout << "--------------------------------------------------------------" << endl;
    cout << "------------Operation on Share Memory--(Read/Write)-----------" << endl;
    cout << "------------Enter 1 to write to the shared memory-------------" << endl;
    cout << "------------Enter 2 to read the shared memory-----------------" << endl;
    cout << "------------Enter 3 to exit the application-------------------" << endl;
    cout << "--------------------------------------------------------------" << endl;
    cout << "Enter option:";
}

bool RecvAndProcessOption(){
    int nInput;
    bool bReturnValue = true;
    cin >> nInput;
    switch (nInput){
    case 1:
        cout << "Write Operation selected" << endl;
        WriteAndPrint();
        bReturnValue = true;
        break;
    case 2:
        cout << "Read Operation selected" << endl;
        ReadAndPrint(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值