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

在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进程通信方式,选择合适的方式取决于具体的应用场景和需求。

你可能感兴趣的:(并发编程,python,开发语言)