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

        进程间通信(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通常用于实现分布式系统和微服务架构中的远程服务调用和数据交换

猜你喜欢

转载自blog.csdn.net/lxd_max/article/details/132210449