python 进程间通信(IPC)(5.1)

2022-09-28 13:24:10 浏览数 (1)

进程间通信(IPC)

文件

通过读写文件来进行变量, 数据, 信息的传递

读写冲突

两个进程同时进行写, 或者一个写一个读, 造成了冲突.

解决读写冲突

互斥锁

代码语言:javascript复制
from multiprocessing import Process, Lock


def save_to_file(index, lock):
    with lock:
        with open("test.log", "a", encoding="utf-8") as f:
            f.write(str(index)   "n")


if __name__ == "__main__":
    process_array = []
    lock = Lock()
    for i in range(10):
        p = Process(target=save_to_file, args=(i, lock))
        process_array.append(p)
        p.start()
    for p in process_array:
        p.join()
    print("done!")

套接字(socket-插座)

通过一个协议, 连接两个进程. 主要就是网络请求.

进程A向百度云上传文件, 进程B向百度云下载文件, 不会有冲突.

管道(了解)

用文件的内存缓冲区作为管道, 实现进程间通信

  • 匿名管道 主进程和子进程进行交互
  • 具名管道 和匿名管道原理是一样的, 不是不相关的进程也可以互相访问

消息队列

就是一个存在内核内存空间中的列表

redis就是消息队列 socket

代码语言:javascript复制
from multiprocessing import Queue

def save_to_queue(index, my_queue):
    my_queue.put(index)


if __name__ == "__main__":
    process_array = []
    my_queue = Queue()
    for i in range(10):
        p = Process(target=save_to_queue, args=(i, my_queue))
        process_array.append(p)
        p.start()
    for p in process_array:
        p.join()

    while True:
        print(my_queue.get())

共享内存(了解)

进程访问内核态同一块内存

代码语言:javascript复制
from multiprocessing import Queue, Array, Value

信号量(了解)

不是用来传递数据的, 是用来传递消息

进程B要等到进程A执行到某一步操作后, 才会启动

进程A->发消息->内核->转发信息->进程B

线程间通信

线程间通信强调的是线程之间传递对象引用

共享变量

线程安全

线程有GIL锁, 但是拿到GIL锁不代表可以一直执行下去.

现代计算机多线程也是A执行一会儿, B执行一会儿这样交替执行.

代码语言:javascript复制
import requests
import time
from threading import Thread


zero = 0

def foo():
    global zero
    for i in range(10**7):
        zero  = 1
        zero -= 1


if __name__ == "__main__":
    process_array = []
    for i in range(2):
        p = Thread(target=foo)
        process_array.append(p)
        p.start()
    for p in process_array:
        p.join()

    print(zero)

解决线程安全

将重要指令包装成原子操作(不可分割的).

  • 加互斥锁
代码语言:javascript复制
import requests
import time
from threading import Thread,Lock


zero = 0
lock = Lock()

def foo():
    global zero
    for i in range(10**6):
        with lock:
            zero  = 1
            zero -= 1


if __name__ == "__main__":
    process_array = []
    for i in range(2):
        p = Thread(target=foo)
        process_array.append(p)
        p.start()
    for p in process_array:
        p.join()

    print(zero)

0 人点赞