Named pipes performance issues

淺唱寂寞╮ 提交于 2019-12-03 16:39:29

After a lot of (manual) profiling, I came up with two insights about the problem:

  1. Libby's pipes is a complex beast. Since it seems to use multiple threads and shows a weird behavior concerning its usage, the manual use of the WinApi was more convienient after all. Furthermore, the performance taken by the actual communication increased. In other words: In a relatively simple IPC-scenario like this, libby's pipes seem to be slower than the WinApi.
  2. Annonymous pipes / using the stdout & stdin seem to be even faster than named pipes.

However, I must add that I still am sort of confused and can't tell whether this is true or I've been crunching the wrong numbers here.

Here's an easy example of how the WinApi implementation in Delphi could look like:

// setup pipes, you'll need one for each direction
// init handles with 0
    CreatePipe(ReadPipe1,       // hReadpipe
               WritePipe1,      // hWritePIpe
               @SecurityAttributes,        // Security
               PIPE_SIZE)                  // Size

    // setup Startupinfo
    FillChar(StartupInfo, Sizeof(StartupInfo), 0);
    StartupInfo.cb := Sizeof(StartupInfo);
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
    StartupInfo.hStdInput := ReadPipe1;
    StartupInfo.hStdOutput := WritePipe2;
    StartupInfo.wShowWindow :=  SW_HIDE; 

    // CreateProcess [...]

    // read
    Win32Check(
            ReadFile(
                  ReadPipe1,  // source
                  (@outputBuffer[1])^,               // buffer-pointer
                  PIPE_BUFFER_SIZE,                 // size
                  bytesRead,                       // returns bytes actually read
                  nil                             // overlapped on default
                  ));
    // send           
    Win32Check(
            WriteFile(
                WritePipe2,
                (@msg[1])^,         // lpBuffer - workarround to avoid type cast
                NumberOfBytesToWrite,
                bytesWritten,       // lpNumberOfBytesWritten
                nil                 // Overlapped   
                ));                          

Maybe you can use named events for IPC signaling. These work fine in Win7 etc when these are local (TEvent.Create('local\myserver'); When you need to do IPC between different sessions (e.g. client app and background windows service), you need more rights etc (default global\ can not be used in win7 due to UAC?). http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devwin32/threadswaitingforatasktobecompleted_xml.html

For example: create an event per connection (with a generated name per connection).

Or take a look at a different IPC named pipe + events implementation : https://micksmix.wordpress.com/2011/06/27/named-pipes-unit-for-delphi/

Btw: you mentioned you used profiling but you could not say what takes the most time? What kind of profiling did you use? Not a "profiler" like AQtime (http://smartbear.com/products/free-tools/aqtime-standard) or AsmProfiler (http://code.google.com/p/asmprofiler/)?

And simple improvement could be: first send the amount of bytes to send (so receiver knows how much data it can expect) then send the data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!