C# 实现进程间通信的几种方式(完善)

目录

引言

一、基本概念

二、常见的IPC方法

1. 管道(Pipes)

2. 共享内存(Shared Memory)

3. 消息队列(Message Queues)

4. 套接字(Sockets)

5. 信号量(Semaphores)

6. 文件映射(File Mapping)

7. 远程过程调用(RPC)

三、总结


引言

进程间通信(IPC)是指在操作系统中,不同进程之间交换数据和信息的机制。在C#中,IPC可以通过多种方式实现,包括文件共享、命名管道、套接字、消息队列、远程过程调用(RPC)等。每种方法都有其特定的应用场景和优缺点。

一、基本概念

  1. 进程(Process)

    • 进程是操作系统中运行的程序实例。每个进程都有自己的内存空间、代码、数据和系统资源。进程之间相互独立,默认情况下无法直接访问彼此的内存空间。
  2. 进程间通信(IPC)

    • IPC允许进程共享资源、同步操作、传递消息等,是进程协作的基础。

二、常见的IPC方法

1. 管道(Pipes)

管道是一种半双工的通信机制,可以在同一台机器上的两个进程之间传输数据。包括匿名管道和命名管道。

应用场景: 常用于本地进程间的简单通信。

技术关键点: 数据流传输,适合父子进程。

// 服务器端
using (var serverPipe = new NamedPipeServerStream("testpipe", PipeDirection.InOut))
{Console.WriteLine("Waiting for client connection...");serverPipe.WaitForConnection(); // 等待客户端连接using (var reader = new StreamReader(serverPipe))using (var writer = new StreamWriter(serverPipe)){writer.WriteLine("Hello from server"); // 向客户端发送消息writer.Flush();string message = reader.ReadLine(); // 读取客户端发送的消息Console.WriteLine("Received from client: " + message);}
}// 客户端
using (var clientPipe = new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut))
{Console.WriteLine("Connecting to server...");clientPipe.Connect(); // 连接到服务器using (var reader = new StreamReader(clientPipe))using (var writer = new StreamWriter(clientPipe)){string message = reader.ReadLine(); // 读取服务器发送的消息Console.WriteLine("Received from server: " + message);writer.WriteLine("Hello from client"); // 向服务器发送消息writer.Flush();}
}

服务器端代码解释:

  • 创建一个命名管道服务器。
  • 等待客户端连接。
  • 使用StreamReaderStreamWriter进行数据读写。

客户端代码解释:

  • 创建一个命名管道客户端。
  • 连接到服务器。
  • 使用StreamReaderStreamWriter进行数据读写。

 

2. 共享内存(Shared Memory)

共享内存允许两个或多个进程访问同一块内存区域,是最快的IPC形式。

应用场景: 高性能要求的场景。

技术关键点: 内存同步,数据一致性。

// 使用MemoryMappedFile创建共享内存
using (var mmf = MemoryMappedFile.CreateNew("MyMap", 1024))
{using (var accessor = mmf.CreateViewAccessor()){// 准备数据byte[] data = new byte[1024];// 写入数据到共享内存accessor.WriteArray(0, data, 0, data.Length);// 读取数据accessor.ReadArray(0, data, 0, data.Length);}
}

代码解释:

  • 创建或打开一个共享内存对象。
  • 使用视图访问器来读写内存数据。
3. 消息队列(Message Queues)

消息队列允许进程通过发送和接收消息来通信,支持异步操作。

应用场景: 分布式系统,异步消息传递。

技术关键点: 消息持久化,异步处理。

// 发送消息
using (var queue = new MessageQueue(@".\Private$\MyQueue"))
{queue.Send("Hello, World!"); // 发送一条消息到队列
}// 接收消息
using (var queue = new MessageQueue(@".\Private$\MyQueue"))
{queue.Formatter = new XmlMessageFormatter(new[] { typeof(string) });var message = queue.Receive(); // 接收消息string content = (string)message.Body; // 读取消息内容Console.WriteLine(content);
}

代码解释:

  • 创建或打开一个消息队列。
  • 使用System.Messaging库发送和接收消息。

 

4. 套接字(Sockets)

套接字支持网络通信,可用于本地或远程进程间通信。

应用场景: 网络应用,实时通信。

技术关键点: 协议选择(TCP/UDP),数据传输稳定性。

// 服务器端
var listener = new TcpListener(IPAddress.Any, 5000);
listener.Start(); // 启动监听
Console.WriteLine("Waiting for connection...");
var client = listener.AcceptTcpClient(); // 接受客户端连接
using (var stream = client.GetStream())
using (var reader = new StreamReader(stream))
using (var writer = new StreamWriter(stream))
{writer.WriteLine("Hello from server"); // 发送消息给客户端writer.Flush();string message = reader.ReadLine(); // 读取客户端消息Console.WriteLine("Received from client: " + message);
}// 客户端
var client = new TcpClient();
client.Connect("localhost", 5000); // 连接到服务器
using (var stream = client.GetStream())
using (var reader = new StreamReader(stream))
using (var writer = new StreamWriter(stream))
{string message = reader.ReadLine(); // 读取服务器消息Console.WriteLine("Received from server: " + message);writer.WriteLine("Hello from client"); // 发送消息给服务器writer.Flush();
}

服务器端代码解释:

  • 创建一个TCP监听器。
  • 等待客户端连接。
  • 使用StreamReaderStreamWriter进行数据读写。

客户端代码解释:

  • 创建一个TCP客户端。
  • 连接到服务器。
  • 使用StreamReaderStreamWriter进行数据读写。

 

5. 信号量(Semaphores)

用于同步多个进程对共享资源的访问。

应用场景: 并发控制,资源管理。

技术关键点: 并发访问控制,资源锁定。

// 使用Semaphore进行进程同步Semaphore semaphore = new Semaphore(initialCount: 1, maximumCount: 1, name: "MySemaphore");semaphore.WaitOne(); // 请求访问共享资源// 执行临界区中的代码semaphore.Release(); // 释放共享资源

代码解释:

  • 创建或打开一个信号量对象。
  • 控制对共享资源的访问。

 

6. 文件映射(File Mapping)

允许进程将文件内容映射到内存中,实现数据共享。

应用场景: 文件共享,数据缓存。

技术关键点: 文件访问同步,内存映射效率。

// 使用FileStream和MemoryMappedFile进行文件映射
using (FileStream fs = new FileStream("data.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, "MyMap", fs.Length, MemoryMappedFileAccess.ReadWrite, null, HandleInheritability.None, false)){using (var accessor = mmf.CreateViewAccessor()){accessor.Write(0, (byte)42); // 写入数据到映射文件Console.WriteLine(accessor.ReadByte(0)); // 读取数据}}
}

代码解释:

  • 使用FileStream打开一个文件。
  • 将文件内容映射到内存。
  • 使用视图访问器来读写内存数据。

 

7. 远程过程调用(RPC)

允许进程调用远程函数,提供分布式计算支持。

应用场景: 分布式系统,服务调用。

技术关键点: 调用序列化,网络通信可靠性。

// 定义服务契约
[ServiceContract]
public interface IMyService
{[OperationContract]string SayHello(string name);
}// 实现服务
public class MyService : IMyService
{public string SayHello(string name){return $"Hello, {name}!";}
}// 配置和托管服务
var host = new ServiceHost(typeof(MyService), new Uri("http://localhost:8000/MyService"));
host.AddServiceEndpoint(typeof(IMyService), new BasicHttpBinding(), "");
host.Open();
Console.WriteLine("Service is running... Press [Enter] to exit.");
Console.ReadLine();
host.Close();// 客户端调用
var factory = new ChannelFactory<IMyService>(new BasicHttpBinding(), new EndpointAddress("http://localhost:8000/MyService"));
var proxy = factory.CreateChannel();
string result = proxy.SayHello("World"); // 调用远程服务
Console.WriteLine(result);
((IClientChannel)proxy).Close();
factory.Close();

服务器端实现步骤:

  • 定义服务契约。
  • 实现服务契约。
  • 使用WCF托管服务。

客户端实现步骤:

  • 创建服务契约的通道工厂。
  • 调用远程方法。

 

三、总结

进程间通信是C#中实现不同进程之间数据交换和信息传递的重要机制。常见的IPC方法包括文件共享、命名管道、套接字、消息队列和远程过程调用。每种方法都有其特定的应用场景和优缺点。

  • 文件共享: 简单易用,但性能较低,需要处理文件锁定和同步问题。
  • 命名管道: 支持双向通信,适用于局域网内的进程间通信。
  • 套接字: 支持跨网络通信,适用于TCP/IP或UDP协议的通信。
  • 消息队列: 支持异步通信和解耦合,适用于分布式系统。
  • 远程过程调用: 允许进程调用远程计算机上的函数或方法,适用于分布式应用。

通过合理选择和使用这些IPC方法,开发者可以实现高效、稳定且可扩展的进程间通信。了解每种方法的原理和应用场景,可以帮助开发者更好地设计和实现复杂的分布式系统。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/462501.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++之位算法

位算法 常见位运算总结 位1的个数 给定一个正整数 n&#xff0c;编写一个函数&#xff0c;获取一个正整数的二进制形式并返回其二进制表达式中 设置位 的个数&#xff08;也被称为汉明重量&#xff09;。 示例 1&#xff1a; 输入&#xff1a;n 11 输出&#xff1a;3 解释…

JAVA利用方法实现四道题

目录 1.给定一个字符串 s &#xff0c;找到 它的第一个不重复的字符&#xff0c;并返回它的索引 。如果不存在&#xff0c;则返回-1 2.计算字符串最后一个单词的长度&#xff0c;单词以空格隔开。&#xff08;注&#xff1a;字符串末尾不以空格为结尾&#xff09; 3.如果在将所…

【教程】Git 标准工作流

前言 Git 是日常开发中常用的版本控制工具&#xff0c;配合代码托管仓库&#xff08;如&#xff0c;Github&#xff0c;GitLab&#xff0c;Gitee 等&#xff09;用来实现多人多版本的协作开发。 但是 Git 的命令纷繁复杂&#xff0c;多如累卵&#xff0c;不可能也不需要全部搞…

基于AI深度学习的中医针灸实训室腹针穴位智能辅助定位系统开发

在中医针灸的传统治疗中&#xff0c;穴位取穴的精确度对于治疗效果至关重要。然而&#xff0c;传统的定位方法&#xff0c;如体表标志法、骨度折量法和指寸法&#xff0c;由于观察角度、个体差异&#xff08;如人体姿态和皮肤纹理&#xff09;以及环境因素的干扰&#xff0c;往…

金融标准体系

目录 基本原则 标准体系结构图 标准明细表 金融标准体系下载地址 基本原则 需求引领、顶层设计。 坚持目标导向、问题导向、结果 导向有机统一&#xff0c;构建支撑适用、体系完善、科学合理的金融 标准体系。 全面系统、重点突出。 以金融业运用有效、保护有力、 管理高…

.NET 8 Web API 中的身份验证和授权

本次介绍分为3篇文章&#xff1a; 1&#xff1a;.Net 8 Web API CRUD 操作.Net 8 Web API CRUD 操作-CSDN博客 2&#xff1a;在 .Net 8 API 中实现 Entity Framework 的 Code First 方法https://blog.csdn.net/hefeng_aspnet/article/details/143229912 3&#xff1a;.NET …

Spring Boot 与 Vue 共铸卓越采购管理新平台

作者介绍&#xff1a;✌️大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 &#x1f345;获取源码联系方式请查看文末&#x1f345; 推荐订阅精彩专栏 &#x1f447;&#x1f3fb; 避免错过下次更新 Springboot项目精选实战案例 更多项目…

字符串统计(Python)

接收键盘任意录入&#xff0c;分别统计大小写字母、数字及其它字符数量&#xff0c;打印输出。 (笔记模板由python脚本于2024年11月02日 08:23:31创建&#xff0c;本篇笔记适合熟悉python字符串并懂得基本编程技法的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xf…

qt QScrollArea详解

1、概述 QScrollArea是Qt框架中的一个控件&#xff0c;它提供了一个可滚动的视图区域&#xff0c;用于显示超出视图大小的内容。这个控件非常有用&#xff0c;尤其是在处理大型表格、文本区域、图像集合或任何需要滚动浏览的内容时。QScrollArea本身不直接显示内容&#xff0c…

HTML 基础标签——元数据标签 <meta>

文章目录 1. `<meta>` 标签概述2. 属性详解2.1 `charset` 属性2.2 `name` 属性2.3 `content` 属性2.4 `http-equiv` 属性3. 其他常见属性小结在 HTML 文档中,元数据标签 <meta> 是一种重要的标签,用于提供关于文档的信息,这些信息不直接显示在网页内容中,但对于…

InnoDB: corruption in the InnoDB tablespace

磁盘空间满和断电都可能导致mysql无法启动&#xff0c;报错如下&#xff1a; InnoDB: corruption in the InnoDB tablespace. Please refer to InnoDB: http://dev.mysql.com/doc/refman/8.0/en/forcing-innodb-recovery.html InnoDB: about forcing recovery. 20241031 10:54:…

Java网络通信

前言 1. 基本知识 通俗一点就是CS就是要下载应用来访问的&#xff0c;BS是在浏览器上面访问的&#xff0c;不用下载 1.1 IP IP地址就是你电脑的主机号&#xff0c;一台设备都有唯一的IP&#xff0c;端口就是程序的唯一标识 这上面就是我们的ip地址了&#xff0c;有IPv4和…

iptables面试题

1、详述iptales工作流程以及规则过滤顺序&#xff1f; iptables过滤的规则顺序是由上至下&#xff0c;若出现相同的匹配规则则遵循由上至下的顺序 2、iptables的几个表以及每个表对应链的作用&#xff1f; Iptables有四表五链 Filter表 : Filter表是iptables中使用的默认表…

【论文笔记】Attention Prompting on Image for Large Vision-Language Models

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Attention Prompting on I…

【spring】Cookie和Session的设置与获取(@CookieValue()和@SessionAttribute())

&#x1f490;个人主页&#xff1a;初晴~ &#x1f4da;相关专栏&#xff1a;程序猿的春天 获取Cookie 使用 Servlet 获取Cookie&#xff1a; Spring MVC 是基于 Servlet API 构建的原始 Web 框架&#xff0c;也是在 Servlet 的基础上实现的 RestController RequestMapping…

Android启动流程_Init阶段

前言 本文将会介绍 Android 启动流程&#xff0c;将基于 Android 10 代码逻辑介绍原生启动过程。 bootloader 上电 -> 加载 recovery 镜像或者 boot 镜像 -> linux kernel 启动 -> 加载 init 进程 -> 加载 zygote 进程 -> systemserver 进程 -> 系统启动 …

MySQL数据库之存储过程的创建与应用

存储过程 procedure 一.存储过程 作用&#xff1a;将经常使用的功能写成存储过程&#xff0c;方便后续重复使用。 二.创建存储过程 三.调用存储过程 call在计算机中是调用的意思 案例1&#xff1a;查看MySQL用户数 如上图所示&#xff0c;这是查看MySQL数据库中的user个数…

7.使用Redis进行秒杀优化

目录 1. 优化思路 总结之前实现的秒杀过程 下单流程 2. 使用Redis完成秒杀资格判断和库存 0. Redis中数据类型的选用 1.将优惠券信息保存到Redis中 2.基于Lua脚本&#xff0c;判断秒杀库存、一人一单&#xff0c;决定用户是否抢购成功 3. 开启新协程&#xff0c;处理数…

终于把DETR搞懂了!Detection Transformer架构详解及使用方法说明

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

Calling short variants with GATK4

计算生物学实验5: Calling short variants with GATK4 1. 实验目的 本实验目的是利用 GATK4 工具准确高效地检测出基因组中的短变异。通过该工具对样本基因组进行分析&#xff0c;旨在发现单核苷酸变异&#xff08;SNV&#xff09;和小的插入缺失&#xff08;Indel&#xff0…