进程通信 , 信号量 , 队列 , 管道 , 共享内存

简介: 进程通信 , 信号量 , 队列 , 管道 , 共享内存

在Python中信号量也是一种锁 , 能够一次给多个线程/进程加锁 ,设置同时访问的数量. 可以通过线程 (threading)和进程(multiprocessing)来调用 , 调用方法为threading.Semaphore/multiprocessing.Semaphore -- 这里的信号量是一种类 , 和互斥锁一样需要通过实例化调用 .

1. Threading模块中的信号量

 
import threading
 
# 创建信号量,参数表示初始的信号量计数值
semaphore = threading.Semaphore(3)  # 限制同时访问资源的线程数量为3
 
def worker():
    with semaphore:
        # 访问共享资源的代码
        print(threading.current_thread().name, "acquired the semaphore")
        # ...
 
# 创建多个线程
threads = []
for i in range(5):
    thread = threading.Thread(target=worker)
    threads.append(thread)
 
# 启动线程
for thread in threads:
    thread.start()
 
# 等待所有线程结束
for thread in threads:
    thread.join()

在上述例子中,threading.Semaphore(3)创建了一个初始计数值为3的信号量。with semaphore语句用于获取信号量,当进入这个语句块时,信号量的计数值会减少;离开时,计数值会增加。如果信号量的计数值为0,那么其他线程必须等待。

2. Multiprocessing模块中的信号量

import multiprocessing
# 创建信号量,参数表示初始的信号量计数值
semaphore = multiprocessing.Semaphore(3)  # 限制同时访问资源的进程数量为3
def worker():
    with semaphore:
        # 访问共享资源的代码
        print(multiprocessing.current_process().name, "acquired the semaphore")
        # ...
# 创建多个进程
processes = []
for i in range(5):
    process = multiprocessing.Process(target=worker)
    processes.append(process)
# 启动进程
for process in processes:
    process.start()
# 等待所有进程结束
for process in processes:
    process.join()

这个例子与线程的示例类似,但使用了multiprocessing.Semaphore。信号量在多进程环境中同样可以用于控制对共享资源的访问。同样,进入with semaphore语句块时,信号量计数值减少,离开时增加。

无论是在多线程还是多进程的场景中,信号量都是一种有效的工具,用于避免竞争条件和控制并发访问共享资源。

二. 进程通信

在Python中,进程通信是指在多进程编程中,不同的进程之间进行信息交流和共享数据的机制。由于每个进程有自己独立的内存空间,因此进程之间的通信需要通过特定的机制来实现。以下是一些Python中常用的进程通信方式:

1. 队列(Queue):

  • multiprocessing.Queue 提供了一个简单的队列,允许多个进程通过放置和获取消息来进行通信。队列是线程安全的,可以用于在多进程之间安全地传递数据。
from multiprocessing import Process, Queue
def worker(queue):
    data = queue.get()
    # 进行处理
    print(data)
if __name__ == "__main__":
    my_queue = Queue()
    process = Process(target=worker, args=(my_queue,))
    process.start()
    my_queue.put("Hello from the main process")
    process.join()

在Python中,queue.get() 是用于从队列中获取数据的方法。这通常用于在多线程或多进程的环境中进行线程间或进程间的安全数据传递。

multiprocessing 模块或 queue 模块中,get() 方法是一个阻塞调用,意味着如果队列中没有可用的数据,调用 get() 的线程或进程将会等待,直到有数据可供获取。一旦有数据可用,get() 会返回队列中的下一个元素,并将其从队列中移除。

2. 管道(Pipe):

  • multiprocessing.Pipe 提供了一种全双工的通信机制,允许两个进程之间进行双向通信。



from multiprocessing import Process, Pipe
def worker(conn):
    data = conn.recv()
    # 进行处理
    print(data)
    conn.send("Hello from the worker process")
if __name__ == "__main__":
    parent_conn, child_conn = Pipe()
    process = Process(target=worker, args=(child_conn,))
    process.start()
    parent_conn.send("Hello from the main process")
    response = parent_conn.recv()
    print(response)
    process.join()

3.共享内存(Value和Array):

  • multiprocessing.Valuemultiprocessing.Array 允许创建在多个进程之间共享的数值或数组。这些对象会被存储在共享内存中,因此可以被多个进程访问。
from multiprocessing import Process, Value
def worker(shared_value):
    # 进行处理
    shared_value.value += 1
    print(shared_value.value)
if __name__ == "__main__":
    counter = Value("i", 0)
    process = Process(target=worker, args=(counter,))
    process.start()
    process.join()

这些是一些常见的Python进程通信方式,选择合适的方式取决于具体的应用场景和需求。

相关文章
|
4天前
|
设计模式 安全 Java
Java面试题:请解释Java中的线程池以及为什么要使用线程池?请解释Java中的内存模型以及如何避免内存泄漏?请解释Java中的并发工具包以及如何实现一个简单的线程安全队列?
Java面试题:请解释Java中的线程池以及为什么要使用线程池?请解释Java中的内存模型以及如何避免内存泄漏?请解释Java中的并发工具包以及如何实现一个简单的线程安全队列?
10 1
|
5天前
|
算法 安全 调度
深入理解操作系统:进程调度与内存管理
【7月更文挑战第10天】本文将深入探讨操作系统的核心机制,即进程调度和内存管理。我们将从理论和实践的角度出发,解释这些机制如何影响系统性能和用户体验。通过分析不同的调度算法和内存分配策略,我们旨在揭示操作系统设计背后的复杂性和精妙之处。
|
10天前
|
消息中间件 分布式计算 网络协议
从管道路由到共享内存:进程间通信的演变(内附通信方式经典面试题及详解)
进程间通信(Inter-Process Communication, IPC)是计算机科学中的一个重要概念,指的是运行在同一系统或不同系统上的多个进程之间互相发送和接收信息的能力。IPC机制允许进程间共享数据、协调执行流程,是实现分布式系统、多任务操作系统和并发编程的基础。
从管道路由到共享内存:进程间通信的演变(内附通信方式经典面试题及详解)
|
1天前
|
安全 API Python
`multiprocessing`是Python的一个标准库,用于支持生成进程,并通过管道和队列、信号量、锁和条件变量等同步原语进行进程间通信(IPC)。
`multiprocessing`是Python的一个标准库,用于支持生成进程,并通过管道和队列、信号量、锁和条件变量等同步原语进行进程间通信(IPC)。
5 0
|
3天前
|
消息中间件 Linux
【Linux】进程间通信——system V(共享内存 | 消息队列 | 信号量)(下)
【Linux】进程间通信——system V(共享内存 | 消息队列 | 信号量)(下)
13 0
|
3天前
|
消息中间件 存储 Linux
【Linux】进程间通信——system V(共享内存 | 消息队列 | 信号量)(上)
【Linux】进程间通信——system V(共享内存 | 消息队列 | 信号量)(上)
9 0
|
3天前
|
安全 Linux 数据格式
【Linux】进程通信----管道通信(下)
【Linux】进程通信----管道通信(下)
14 0
|
3天前
|
Unix Linux
【Linux】进程通信----管道通信(上)
【Linux】进程通信----管道通信(上)
19 0
|
4天前
|
设计模式 安全 NoSQL
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
9 0
|
4天前
|
存储 Java 程序员
Java面试题:方法区在JVM中存储什么内容?它与堆内存有何不同?
Java面试题:方法区在JVM中存储什么内容?它与堆内存有何不同?
26 10