Inter-process communication in Windows (3)

Source: Internet
Author: User

From: http://hi.baidu.com/_achillis/blog/item/bdaa0d943d4b130e7bf48080.html

5. Named Pipe (Named Pipe) and mail slot)

As mentioned above, if it is literally understood, inter-process communication can also be achieved through disk files. However, writing information to a disk file and reading it from the disk file by another process is slow. Of course, due to the existence of the File Buffer (cache), The write and read operations on disk files may not always go through the disk, but this is not guaranteed. In addition, common file operations do not provide means for inter-process synchronization. Therefore, it is unrealistic to implement inter-process communication through common disk files. However, this also reminds us that if we can implement a special file, so that the read and write operations on the file are only in the buffer zone (rather than written to the disk), and to implement inter-process synchronization, that is not a bad idea. A named pipe is such a special file. In fact, the named pipe is not only such a special file, but also a network communication mechanism, only when both parties of the communication exist on the same machine, it falls into the scope of inter-process communication described in this article.
Since a named pipe is a special file, its creation, opening, reading and writing operations can basically be implemented using relevant resources in the file system. Of course, this is, after all, a special file. for users, the biggest difference is that this is a "first-in-first-out" byte stream and cannot perform lseek () operations on it.
First, let's take a look at the creation of named pipelines. The windows Win32 API provides a pair of library functions: createnamedpipea () and createnamedpipew (). The former is used for ASCII code strings, the latter is used for Unicode strings. In fact, the former only converts 8-bit characters into Unicode before calling the latter. Calling createnamedpipew () is roughly as follows:

[Code] handle = createnamedpipew (L "[a] \\\\\. \ PIPE \ mycontrolpipe [/url]",
Pipe_access_duplex,
Pipe_type_message | pipe_readmode_message | pipe_wait,
...); [/Code]

The pipeline name here is actually "\. \ PIPE \ mycontrolpipe". The previous "\." indicates the local machine, while "\ PIPE \ mycontrolpipe" indicates the path name. If you replace "." With the host name, it can be an object on another machine. The pipe_access_duplex parameter indicates that the "duplex" is to be established, that is, the pipeline that can communicate in two directions. Another parameter is a flag, indicating that the pipeline to be established adopts the "message" mode, rather than the byte stream mode for read and write, and is a blocking mode, that is, waiting for read and write.
Createnamedpipew () creates a named pipe by calling ntcreatenamedpipefile (). This is the only system call provided by the Windows Kernel for the named pipe:

[Code] ntstatus stdcall
Ntcreatenamedpipefile (phandle filehandle, access_mask desiredaccess,
Pobject_attributes objectattributes, pio_status_block iostatusblock,
Ulong publish access, ulong createdisposition, ulong createoptions,
Ulong namedpipetype, ulong readmode, ulong completionmode,
Ulong maximuminstances, ulong inboundquota, ulong outboundquota,
Plarge_integer defaulttimeout)
{
Named_pipe_create_parameters buffer;

......
If (defatimetimeout! = NULL)
{
Buffer. defaulttimeout. quadpart = defaulttimeout-> quadpart;
Buffer. timeoutspecified = true;
}
Else
{
Buffer. timeoutspecified = false;
}
Buffer. namedpipetype = namedpipetype;
Buffer. readmode = readmode;
Buffer. completionmode = completionmode;
Buffer. maximuminstances = maximuminstances;
Buffer. inboundquota = inboundquota;
Buffer. outboundquota = outboundquota;

Return iocreatefile (filehandle, desiredaccess, objectattributes, iostatusblock,
Null, file_attribute_normal, encrypted access, createdisposition,
Createoptions, null, 0, createfiletypenamedpipe, (pvoid) & buffer,
0 );
} [/Code]
In Windows, the file system is part of the I/O subsystem, the file is created by iocreatefile (), and The createfiletypenamedpipe parameter is a file type code, it determines that the created pipe is the name of a special file. As for how iocreatefile () creates such a special file, it is no longer within the scope of this article.
Generally, the named pipeline is created by the "server" thread. After the pipeline is created, a Win32 API library function connectnamedpipe () must be called (), wait for the "client" thread to open this named pipe, so that both parties establish a point-to-point connection (note that the connect here is totally different from the connect in the socket mechanism ).

[Code] bool stdcall
Connectnamedpipe (handle hnamedpipe,
Lpoverlapped)
{
Pio_status_block iostatusblock;
Io_status_block iosb;
Handle hevent;
Ntstatus status;

If (lpoverlapped! = NULL)
{
Lpoverlapped-> internal = status_pending;
Hevent = lpoverlapped-> hevent;
Iostatusblock = (pio_status_block) lpoverlapped;
}
Else
{
Iostatusblock = & iosb;
Hevent = NULL;
}

Status = ntfscontrolfile (hnamedpipe, hevent, null, null, iostatusblock,
Fsctl_pipe_listen, null, 0, null, 0 );
If (lpoverlapped! = NULL) & (status = status_pending ))
Return true;

If (lpoverlapped = NULL) & (status = status_pending ))
{
Status = ntwaitforsingleobject (hnamedpipe, false, null );
If (! Nt_success (Status ))
{
Setlasterrorbystatus (Status );
Return false;
}
Status = iosb. status;
}

If ((! Nt_success (Status) & status! = Status_pipe_connected) |
(Status = status_pending ))
{
Setlasterrorbystatus (Status );
Return false;
}
Return true;
} [/Code]
The actual operation is completed by ntfscontrolfile (), while ntfscontrolfile () is a bit like fcntl () in Linux (), it is often used to implement many different operations except standard "read" and "write.
The "client" thread opens a file to establish a connection with the "server" thread, which is opened as a named pipe for a special file. Windows does not provide system calls for this purpose, but directly uses ntopenfile (). For example:

[Code] status = ntopenfile (& filehandle, file_generic_read, & objectattributes, & iosb,
File_pai_read | file_pai_write,
File_synchronous_io_nonalert); [/Code]
The file_synchronous_io_nonalert parameter is used to indicate that access to files will be synchronized or blocked. The file name to be opened is in the data structure objectattributes, so it cannot be seen here. Of course, the file name must be the same as that used by the "server. It can be seen that the "client" thread does not have to know that this is a named pipe, or even a special file, but treats it as a general file.
In the simplest case, this is enough. Now we can communicate through the established connection. The specific operations are the same as reading/writing common files. When reading a common file, the thread will also be blocked (if the content to be read is not already in the buffer). At this time, the thread will wait mainly for the disk to complete its physical reading process, after the disk completes its reading process, the interruption will remove its blocking, which is equivalent to executing a V operation. In contrast, for named pipelines, the threads that start read operations will also be blocked (if there are no data or packets that have arrived ), at this time, the other thread of the pipeline is waiting to write data to the pipeline. When the other party writes data to the pipeline, the thread blocking of the waiting party is removed, which constitutes a V operation. Therefore, the reading/writing of common files also includes the synchronization mechanism, but it is usually the synchronization between processes and external devices (or external physical processes, what the named pipeline requires is synchronization between processes, but this is not essentially different. As a matter of fact, readers will see in the future that wait mechanisms such as ntwaitforsingleobject () are often used in device drivers, and this is the basis for the implementation of device drivers.
Generally, if you start the read operation when there is no data in the pipeline, the thread will be blocked. To avoid blocking, you can use peeknamedpipe () to check whether packets have arrived.

[Code] bool stdcall
Peeknamedpipe (handle hnamedpipe, lpvoid lpbuffer,
DWORD nbuffersize, lpdword lpbytesread,
Lpdword lptotalbytesavail, lpdword lpbytesleftthismessage)
{
Pfile_pipe_peek_buffer buffer;
Io_status_block iosb;
Ulong buffersize;
Ntstatus status;

Buffersize = nbuffersize + sizeof (file_pipe_peek_buffer );
Buffer = rtlallocateheap (rtlgetprocessheap (), 0, buffersize );

Status = ntfscontrolfile (hnamedpipe, null, & iosb,
Fsctl_pipe_peek, null, 0, buffer, buffersize );
If (status = status_pending)
{
Status = ntwaitforsingleobject (hnamedpipe, false, null );
If (nt_success (Status) status = iosb. status;
}
If (status = status_buffer_overflow)
{
Status = STATUS_SUCCESS;
}

......

If (lptotalbytesavail! = NULL)
{
* Lptotalbytesavail = buffer-> readdataavailable;
}
If (lpbytesread! = NULL)
{
* Lpbytesread = iosb. Information-sizeof (file_pipe_peek_buffer );
}
If (lpbytesleftthismessage! = NULL)
{
* Lpbytesleftthismessage = buffer-> messagelength-
(Iosb. Information-sizeof (file_pipe_peek_buffer ));
}
If (lpbuffer! = NULL)
{
Memcpy (lpbuffer, buffer-> data,
Min (nbuffersize, iosb. Information-sizeof (file_pipe_peek_buffer )));
}
Rtlfreeheap (rtlgetprocessheap (), 0, buffer );

Return (true );
} [/Code]
Similarly, the actual query is completed by ntfscontrolfile (), but another "command code" is used ".
In addition to the named pipe, the "Mailslot" is also a special file similar to that provided by the channel, but it only provides a connectionless communication mechanism. Generally, this connectionless communication is called a "datagram" mechanism, and the Named Pipe

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.