我试图找出D中可用于IPC的方法,主要是命名管道。我知道std.process包含来自相关进程的未命名管道的函数,尽管我更关注ipc与不相关的双向进程。我在想我可能需要最终使用本地套接字,或者查看共享内存。
有没有例子可以做到这一点?
答案 0 :(得分:6)
在Unix上,您可以使用std.socket创建一个与TCP套接字类似的unix域套接字,但仅限本地。这是一些示例代码:
// SERVER
import std.socket;
void main() {
auto listener = new Socket(AddressFamily.UNIX, SocketType.STREAM);
listener.bind(new UnixAddress("/home/me/uds"));
listener.listen(10);
/*while(1)*/ {
auto soc = listener.accept();
soc.send("cool\n");
soc.close();
}
listener.close();
import core.sys.posix.unistd;
unlink("/home/me/uds");
}
客户:
void main() {
auto soc = new Socket(AddressFamily.UNIX, SocketType.STREAM);
soc.connect(new UnixAddress("/home/me/uds"));
import std.stdio;
char[1222] buf;
writeln(buf[0 .. soc.receive(buf)]);
soc.close();
}
他们唯一需要了解的是消息的含义(当然),以及socket的文件系统路径。
Unix也有命名管道,但它们不像unix域套接字(或Windows命名管道)那样是双向的
如果你想要一个unix命名管道,它们被称为FIFO文件,并使用mkfifo系统API函数。您可以使用import core.sys.posix.sys.stat;
访问它,然后以与C中相同的方式使用它:传递一个字符串和模式来创建文件,不要忘记检查返回值,然后使用它来读/写它常规的Unix文件功能,例如read
,write
,close
,全部来自import core.sys.posix.unistd;
。有关这些功能,请参阅C文档,例如man 2 read
或man 3 mkfifo
如果您使用的是Linux,或只是在网上搜索这些网页。
但我认为unix域套接字是你正在寻找的,它的工作原理基本上与其他套接字相同,如上例所示。
Windows做的事情有所不同,D标准库甚至不包含OS API函数原型。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365150%28v=vs.85%29.aspx
使用该函数创建命名管道,为其提供其他进程可以使用的路径名(类似于Unix域套接字,但不在统一文件系统中)。然后使用CreateFile函数打开管道,之后,您可以像任何其他文件一样与它通信。
有两种获取函数原型的方法,因此您可以从D调用这些函数。一种是自己复制/粘贴它们,如下所示:
extern(Windows)
HANDLE CreateNamedPipeA(
LPCTSTR lpName,
DWORD dwOpenMode,
DWORD dwPipeMode,
DWORD nMaxInstances,
DWORD nOutBufferSize,
DWORD nInBufferSize,
DWORD nDefaultTimeOut,
LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
首先,import core.sys.windows.windows;
获取基本的Windows类型定义,然后只需将类似的符号添加到您的文件中。它与MSDN相同,只是删除了 In 之类的内容。 (您也可以将它们更改为D in
关键字。)
最重要的是在名称中添加了A或W.有关Unicode与ANSI名称的Microsoft文档底部提到了这一点。 A版本采用ascii字符串。 W版本在D中采用utf-16,wstring
。建议使用W版本,但在某些情况下A版本更容易使用。
或者,您可以从此处下载预制的win32绑定:https://github.com/AndrejMitrovic/DWinProgramming/tree/master/WindowsAPI并在构建时使用它们。
如果您只需要几个函数,我更喜欢复制/粘贴以避免依赖,但如果您正在进行大量的Windows API工作,请下载完整的绑定。
我在D中编写了一个使用这些技术的跨平台终端模拟器:https://github.com/adamdruppe/terminal-emulator
可拆卸部分使用unix域套接字服务器: https://github.com/adamdruppe/terminal-emulator/blob/master/detachable.d
可连接部分是UDS客户端 https://github.com/adamdruppe/terminal-emulator/blob/master/attach.d
Windows模拟器核心使用专门的命名管道来执行我自己的异步'匿名'管道,而不是你的用例,但显示了如何调用这些函数: https://github.com/adamdruppe/terminal-emulator/blob/master/terminalemulator.d
共享内存是你可以做的另一件事,但是期待D库的帮助很少,你必须使用操作系统功能。但它并不难,至少在Unix上有函数原型:import core.sys.posix.sys.shm并使用与C中相同的函数。
我从未真正在Windows上完成它,但快速搜索说你可以制作一个内存映射文件:http://msdn.microsoft.com/en-us/library/windows/desktop/aa366551%28v=vs.85%29.aspx
或许,也许只会从phobos获得帮助:http://dlang.org/phobos/std_mmfile.html但是,我再也没有尝试过这个。当我需要共享内存时,我只是做了shmget等Unix函数(这是在我的simpledisplay.d https://github.com/adamdruppe/arsd/blob/master/simpledisplay.d中使用它来与X服务器通信)。但最重要的是,Unix域套接字基本上与TCP套接字和Phobos'相同。 std.socket有帮助。
其他所有内容都与在C中完成相同。