进程间通信的编程方式(IPC)及实验

news2024/11/27 14:37:11

        进程间通信(IPC)方式

目录

Socket

管道

匿名管道

消息队列

共享内存

信号

远程过程调用


Socket

        Socket编程是一种在计算机网络中进程间通信的编程方法。Socket提供了一种在不同主机上运行的进程之间传输数据的机制。通过使用Socket API,开发者可编写用于发送和接收数据的客户端和服务器应用程序。

        Scope:Socket通常用于实现C-S架构的网络应用程序,如Web服务器、聊天应用程序等

        以下是一Python Socket编程示例,包括一个TCP回显服务器和一个TCP客户端。

        客户端:

import socket

def main():
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect(('localhost', 12345))

    while True:
        message = input("Enter message to send (or 'exit' to quit): ")
        if message == 'exit':
            break

        client_socket.sendall(message.encode())
        response = client_socket.recv(1024)
        print(f"Received: {response.decode()}")

    client_socket.close()

if __name__ == "__main__":
    main()

# 客户端连接到本地主机的端口12345上的服务器。
# 客户端从用户输入获取消息,将其发送到服务器,并接收服务器的回显响应。
# 当用户输入“exit”时,客户端断开连接并退出。

         服务器:

import socket

def main():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(('localhost', 12345))
    server_socket.listen(5)

    print("Server is listening on port 12345...")

    while True:
        client_socket, client_address = server_socket.accept()
        print(f"Connection from {client_address}")

        data = client_socket.recv(1024)
        while data:
            print(f"Received: {data.decode()}")
            client_socket.sendall(data)
            data = client_socket.recv(1024)

        print("Closing connection")
        client_socket.close()

if __name__ == "__main__":
    main()

# 服务器在本地主机的端口12345上监听连接。
# 当客户端连接到服务器时,服务器会接收客户端发送的数据,并将其回显(发送)回客户端。
# 当客户端断开连接时,服务器关闭与客户端的连接并继续监听新的连接。

管道

        管道(Pipe):管道是一种基于字节流的通信方式,通常用于具有父子关系的进程之间的通信。

        scope:管道通常用于实现命令行程序的输入输出重定向和管道操作

        以下示例用python实现,用os.pipe()在父子进程之间进行通信。

import os

def main():
    r, w = os.pipe()

    if os.fork():
        # 父进程
        os.close(w)
        r = os.fdopen(r)
        print("Parent: Received message:", r.read())
        r.close()
    else:
        # 子进程
        os.close(r)
        w = os.fdopen(w, 'w')
        w.write("Hello from child process!")
        w.close()

if __name__ == "__main__":
    main()

        更常用的,Linux中的命令比如 

# cat命令读取名为input.txt文件内容,并传递给grep命令过滤包含信息的行,过滤结果保存到名为output.txt的文件中。
cat input.txt | grep 'pattern' > output.txt

示例中涉及到三个进程:

  1. cat命令:这个进程负责读取input.txt文件的内容。cat命令将文件内容输出到标准输出(stdout)。

  2. grep命令:这个进程负责从标准输入(stdin)读取数据(即cat命令的输出),并过滤出包含特定模式的行。grep命令将过滤后的结果输出到标准输出。

  3. 输出重定向(>):这个操作将grep命令的输出重定向到output.txt文件中,而不是显示在屏幕上。

匿名管道

        匿名管道(Anonymous Pipe):匿名管道是一种基于文件描述符的通信方式,通常用于具有父子关系的进程之间的通信。

        Scope:匿名管道通常用于实现多进程并行计算和数据处理任务。

        Python示例,展示了如何使用multiprocessing.Pipe()在父子进程之间进行通信:

from multiprocessing import Process, Pipe

def child(conn):
    conn.send("Hello from child process!")
    conn.close()

def main():
    parent_conn, child_conn = Pipe()
    p = Process(target=child, args=(child_conn,))
    p.start()

    print("Parent: Received message:", parent_conn.recv())
    p.join()

if __name__ == "__main__":
    main()

消息队列

        消息队列(Message Queue):消息队列是一种基于消息的通信方式,可以用于任意关系的进程之间的通信。比如提供了更高级功能和特性的:RabbitMQ 和 Celery等等。 

        Scope:消息队列通常用于实现分布式系统和微服务架构中的异步通信和任务分发

        以下示例展示了如何使用multiprocessing.Queue()在两个进程之间进行通信:

from multiprocessing import Process, Queue

def producer(queue):
    queue.put("Hello from producer process!")

def consumer(queue):
    print("Consumer: Received message:", queue.get())

def main():
    queue = Queue()
    p1 = Process(target=producer, args=(queue,))
    p2 = Process(target=consumer, args=(queue,))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

if __name__ == "__main__":
    main()

共享内存

        共享内存(Shared Memory):共享内存是一种基于内存的通信方式,可以用于任意关系的进程之间的通信。共享内存允许多个进程访问同一块内存区域,从而实现进程间的数据共享。
        Scope:共享内存通常用于实现高性能计算和实时系统中的数据交换和同步

        以下示例展示了如何使用multiprocessing.Value()在两个进程之间共享内存

from multiprocessing import Process, Value

def increment(shared_value):
    shared_value.value += 1

def main():
    shared_value = Value('i', 0)
    print("Initial value:", shared_value.value)

    p = Process(target=increment, args=(shared_value,))
    p.start()
    p.join()

    print("Final value:", shared_value.value)

if __name__ == "__main__":
    main()

信号

        信号(Signal):信号是一种基于事件的通信方式,用于通知进程有关特定事件(如实现进程管理(如启动、停止、重启等)、错误处理(如段错误、浮点异常等)和状态通知(如子进程终止、终端关闭等)等功能。
        Scope:信号通常用于实现进程管理、错误处理和状态通知等功能。
        以下Python示例展示了如何使用signal模块处理信号

import os
import signal
import time

def signal_handler(signum, frame):
    print(f"Received signal {signum} at {time.time()}")

def main():
    # 注册信号处理函数  
    signal.signal(signal.SIGUSR1, signal_handler)

    # 获取当前进程ID
    pid = os.getpid()
    print(f"Process ID: {pid}")

    # 循环等待信号
    while True:
        print("Waiting for signal...")
        time.sleep(10)

if __name__ == "__main__":
    main()

远程过程调用

        远程过程调用(Remote Procedure Call,RPC):RPC是一种允许在远程计算机上执行函数或方法的通信方式。RPC隐藏了底层通信细节,使得调用远程函数就像调用本地函数一样简单。以下Python示例展示了如何使用xmlrpc库实现一个简单的RPC服务器和客户端:
        服务器:

from xmlrpc.server import SimpleXMLRPCServer

def add(x, y):
    return x + y

def main():
    server = SimpleXMLRPCServer(('localhost', 12345))  # 监听本地主机的端口12345
    server.register_function(add, 'add')  # 服务器注册了一个名为add的函数,用于将两个数相加
    print("RPC server is listening on port 12345...")
    server.serve_forever()

if __name__ == "__main__":
    main()

        客户端:

import xmlrpc.client

def main():
    proxy = xmlrpc.client.ServerProxy('http://localhost:12345')  # 连接到RPC服务器
    result = proxy.add(1, 2)  # 客户端使用ServerProxy对象调用远程的add函数,并接收返回结果
    print("Result:", result)

if __name__ == "__main__":
    main()

        Scope:RPC通常用于实现分布式系统和微服务架构中的远程服务调用和数据交换

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ABC300

ABC300E 题面 思路 对于投骰子,最后一步可能得到1、2、3、4、5、6,那么对应的最后一步之前的数是n/1、n/2、n/3、n/4、n/5,n/6。并且每个数字(1、2、3、4、5、6)得到的概率是一样的,即为1/6。 也就是F(n…

Jmeter(七) - 从入门到精通 - 建立数据库测试计划实战<MySQL数据库>(详解教程)

1.简介 在实际工作中,我们经常会听到数据库的性能和稳定性等等,这些有时候也需要测试工程师去评估和测试,上一篇文章主要介绍了jmeter连接和创建数据库测试计划的过程,在文中通过示例和代码非常详细地介绍给大家,希望对各位小伙伴…

cpolar的基础使用方法

如何使用cpolar内网穿透? 文章目录 如何使用cpolar内网穿透?前言1. 在群辉NAS系统下安装cpolar套件2. 管理隧道列表3. 创建固定数据隧道 前言 群晖作为大容量存储系统,既可以作为个人的私有存储设备,也可以放在小型企业中作为数据…

别再用人工巡检了,教你一个简单好用的新技巧

当今社会中,计算机设备扮演着不可或缺的角色,它们在个人生活、商业活动和科技创新中都具有重要地位。 无论是个人用户还是企业,UPS监控都是确保计算机设备稳定运行的关键环节。通过有效的UPS监控,我们能够在电力波动或中断时保护硬…

python中的迭代器和生成器

一、迭代器 支持迭代的容器,如列表(list)、元组(tuple)、字典(dict)、集合(set)这些序列式容器。 自定义迭代器的类中必须实现以下2个方法: __next__(self)…

Netty:用forEachByte遍历处理ByteBuf中的可读字节

说明 io.netty.buffer.ByteBuf的forEachByte(ByteProcessor processor)用指明的ByteProcessor 遍历ByteBuf中的可读字节。遍历的时候用升序遍历。 -这个函数可以在ByteBuf中寻找某个字节首次出现的位置,或者首次不是某个字节的位置。 如果已经遍历完了可读字节但还…

简单的基于SpringBoot的学生成绩管理系统java jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 简单的基于SpringBoot的学生成绩管理系统 系统有2权限…

LeetCode面向运气之Javascript—第26题-删除有序数组中的重复项-99.18%

LeetCode第26题-删除有序数组中的重复项 题目要求 一个升序排列的数组nums ,请你原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度。元素的相对顺序应该保持 一致 。然后返回 nums 中唯一元素的个数。 原地 说是一个…

领航优配:股市看盘的几个小技巧?

股市看盘是每个股民不可或缺的一项技能,它能够帮助股民更好地剖析股票的走势,从而做出更明智的出资决策。可是,股市行情千变万化,要想达到精准的猜测与判断,需求把握一些小技巧。本文将分享几个股市看盘的小技巧&#…

使用CANape查看blf数据

blf数据不像mf4那样自带信号数据库,因为它是记日志用的,一般情况下要尽可能的小,所以,解析blf数据要单独有个数据库文件,一般是dbc或者arxml,我这里用dbc做示范,解析之前要先加载dbc&#xff0c…

微服务Ribbon-负载均衡策略和饥饿加载

目录 一、负载均衡策略 1.1 负载均衡策略介绍 1.2 自定义负载均衡策略 二、饥饿加载 (笔记整理自bilibili黑马程序员课程) 一、负载均衡策略 1.1 负载均衡策略介绍 负载均衡的规则都定义在IRule接口中,而IRule有很多不同的实现类&…

HCIP-linux和kvm(ks配置文件自动化安装及console连虚拟机有问题)

1、linux linux安装教程参考,https://blog.51cto.com/cloudcs/5245337 yum源配置 本地yum源配置: 8版本配置:将光盘iso挂载到某个目录,/dev/cdrom是/dev/sr0软链接,# mount /dev/cdrom /mnt,# ls /mnt Ap…

siMLPe:Human Motion Prediction

Back to MLP: A Simple Baseline for Human Motion Prediction解析 摘要1. 简介2. Related Work2.1 基于RNN的人体运动预测2.2 基于GCN的人体运动预测2.3 基于 Attention 的人类运动预测2.4 总结 3. siMLPe3.1 离散余弦变换(Discrete Cosine Transform (DCT)&#x…

使用go获取链上数据之主动拉取-连接数据库

上一篇文章,我们完成了基础环境的搭建,并通过viper完成了配置文件的读取,本章,我们将要完成使用gorm连接数据库,并插入一条数据 1、配置数据库连接 1.1、新建db.go 对数据库的操作,我们使用的是gorm类库&…

个人理解Java的浅克隆与深克隆

浅克隆 浅克隆只会克隆基本数据属性,而不会克隆引用其他对象的属性,String类型除外。(String对象是不可修改的对象,每次修改其实都是新建一个新的对象,而不是在原有的对象上修改,所以当修改String属性时其…

vue2.7如何使用vue-i18n

版本: vue:2.7.0 vue-i18n:8.28.2 一、下载 npm i vue-i18n8.28.2二、新建 新建一个文件,例如:lang,项目结构如下: index.js: import Vue from vue import VueI18n from vue-i18n…

函数的递归

1、什么是递归? 程序调用自身的编程技巧称为递归。 递归作为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解&#x…

最强自动化测试框架Playwright-操作指南(3)-PO模式

playwright支持PO模式 创建页面对象 class SearchPage:def __init__(self, page):self.page pageself.search_term_input page.get_by_role("searchbox", name"输入搜索词")def navigate(self):self.page.goto("https://bing.com")def searc…

《人脸识别技术应用安全管理规定(征求意见稿)》,需要关注三个焦点

目录 严防人脸信息采集与滥用 规范人脸识别信息的处理 保障人脸识别技术的安全 人脸识别主要有三类风险 近日,国家互联网信息办公室发布《人脸识别技术应用安全管理规定(试行)(征求意见稿)》公开征求意见的通知。 …

甄品焕新|燕千云服务请求预警功能上线,燕小千AIGC能力再升级

​ 燕千云数智化业务服务平台发布了1.23.0版本,此次版本上线了服务请求预警功能,增加呼叫中心服务场景中的通话质检功能,提高了企业IT服务效率。此次还升级了燕小千AIGC能力,不仅可以实时预估文档学习时间,还可以一键分…