Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何检测多处理。管道已满?_Python_Python 3.x_Ipc_Python Multiprocessing - Fatal编程技术网

Python 如何检测多处理。管道已满?

Python 如何检测多处理。管道已满?,python,python-3.x,ipc,python-multiprocessing,Python,Python 3.x,Ipc,Python Multiprocessing,问题描述:我正在用Python进行多处理,并使用multiprocessing.Pipe()在进程之间进行通信。我已经搜索了很多,但仍然找不到一种方法来检测管道是否已满。例如,WritePie进程不断地将数字放入两个不同的管道(奇数和偶数),readPipe进程不断地从这两个管道读取。但是,从奇数管道读取数据的速度要快得多,因此偶数管道将充满数据。此时,WritePie进程将被阻塞,而readPipe进程仍在等待从奇数管道读取,这将导致死锁 我的问题:是否有任何方法可以检测到管道已满,这样我们就

问题描述:我正在用Python进行多处理,并使用multiprocessing.Pipe()在进程之间进行通信。我已经搜索了很多,但仍然找不到一种方法来检测管道是否已满。例如,WritePie进程不断地将数字放入两个不同的管道(奇数和偶数),readPipe进程不断地从这两个管道读取。但是,从奇数管道读取数据的速度要快得多,因此偶数管道将充满数据。此时,WritePie进程将被阻塞,而readPipe进程仍在等待从奇数管道读取,这将导致死锁

我的问题:是否有任何方法可以检测到管道已满,这样我们就可以在管道仍在运行时停止将数字放入满管道,并将数字放入仍有空间的管道

from multiprocessing import Process, Pipe


def writePipe(sendNumberOdd, sendNumberEven):
    i = 0
    while True:
        if i % 2 == 0:
            sendNumberEven.send(i)
        else:
            sendNumberOdd.send(i)
        i += 1

def readPipe(recvNumberOdd, recvNumberEven):
    countEven = 0
    while True:
        countEven += 1
        print(countEven, recvNumberEven.recv())

        countOdd = 0
        while countOdd < 50:
            countOdd += 1
            print (countOdd, recvNumberOdd.recv())



if __name__ == '__main__':
    recvNumberOdd, sendNumberOdd = Pipe(duplex=False)
    recvNumberEven, sendNumberEven = Pipe(duplex=False)

    write = Process(target=writePipe, args=(sendNumberOdd, sendNumberEven))
    read = Process(target=readPipe, args=(recvNumberOdd, recvNumberEven))
    write.start()
    read.start()

    sendNumberOdd.close()
    sendNumberEven.close()
来自多处理导入进程的管道 def WritePie(SendNumberId,SendNumberReven): i=0 尽管如此: 如果i%2==0: SendNumberReven.send(一) 其他: sendnumberd.send(i) i+=1 def读取管道(RecvNumber奇数、RecvNumber偶数): 偶数=0 尽管如此: 偶数+=1 打印(countEven,recvNumberEven.recv()) count奇数=0 当countOdd<50时: count奇数+=1 打印(countOdd,recvNumberOdd.recv()) 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': recvNumberOdd,sendNumberOdd=管道(双工=假) RECVNUMBEREEN,sendNumberEven=管道(双工=假) write=Process(target=writepe,args=(sendNumberOdd,sendNumberEven)) read=Process(target=readPipe,args=(recvNumberOdd,recvnumber偶数)) write.start() read.start() sendnumberdd.close() sendNumberEven.close() 未经测试的提案

class Connection(multiprocessing.Connection):
    def __init__(self, maxsize=0):
        self.__maxsize = maxsize
        self.size = 0
        self.__lock = multiprocessing.Lock

    def send(self, obj):
        with self.__lock:
            self.size += sizeof(obj)
        super().send(obj)

    def recv(self):
        _recv = super().recv()
        with self.__lock:
            self.size -= sizeof(_recv)
        return _recv

    def full(self):
        if self.__maxsize > 0:
            return self.size >= self.__maxsize
        return None

def Pipe(maxsize=0, duplex=True):
    return Connection(maxsize), Connection(maxsize)

执行
poll()
检查是否有数据准备就绪

Python»文档:

例如:

if recvNumberEven.poll():
    countEven += 1
    print(countEven, recvNumberEven.recv())
对于这两种情况,可选择使用
wait(…)

您可以使用
选择
模块中的功能来执行输出管道是否已满的测试

import select
import multiprocessing.connection as mpc


def pipe_full(conn):
    r, w, x = select.select([], [conn], [], 0.0)
    return 0 == len(w)


i, o = mpc.Pipe(duplex=False)

n = 0
while not pipe_full(o):
    o.send(n)
    n += 1

print('{} items fit.'.format(n))

谢谢你的回答。然而,我认为你误解了我的问题。我需要的是一种检测管道是否已满的方法,以停止从WritePie进程向管道发送更多数据,从而防止死锁。同时,poll()只能用于知道管道中是否有任何数据要读取,因此在这种情况下它没有帮助。我需要类似于Queue.put(block=False)或Queue.put_nowait的东西,它会引发队列。完全异常,以便我可以处理管道已满的情况。@Le Quoc Khanh:没有管道已满的情况,您唯一的解决方法是防止
消费者
过程永远流浪。再次感谢您,但根据我的理解,多处理。队列建立在管道之上,它有一些机制来检测和引发队列。队列已满时发生完全异常。我试着阅读多处理库中queues.py的源代码,发现它使用了某种Boundedsemaphore进行检测,但我仍然不理解其逻辑。您对此有什么线索吗?
队列
使用大小计数器处理此问题,如果大小计数器等于缓冲区中的数据,则条件FULL为
True
。但是为什么要重新发明轮子,为什么
Queue
不符合您的需要?因为队列的性能非常慢(比管道慢约3倍),因为队列是通过某种机制实现的,我不需要这种机制(我只在半双工中使用单生产者、单消费者IPC)。因为我必须实时处理大量数据,所以我必须选择使用管道而不是队列。请您更详细地解释一下队列是如何工作的,以检测它是否已满,以及我如何对管道应用类似的方法。我真的很感激。非常感谢你。
Wait till an object in object_list is ready.  
Returns the list of those objects in object_list which are ready.
import select
import multiprocessing.connection as mpc


def pipe_full(conn):
    r, w, x = select.select([], [conn], [], 0.0)
    return 0 == len(w)


i, o = mpc.Pipe(duplex=False)

n = 0
while not pipe_full(o):
    o.send(n)
    n += 1

print('{} items fit.'.format(n))